mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-30 08:04:13 +08:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
Steffen Klassert says: ==================== pull request (net): ipsec 2018-05-07 1) Always verify length of provided sadb_key to fix a slab-out-of-bounds read in pfkey_add. From Kevin Easton. 2) Make sure that all states are really deleted before we check that the state lists are empty. Otherwise we trigger a warning. 3) Fix MTU handling of the VTI6 interfaces on interfamily tunnels. From Stefano Brivio. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
1822f638e8
@ -375,6 +375,7 @@ struct xfrm_input_afinfo {
|
|||||||
int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
|
int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
|
||||||
int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
|
int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
|
||||||
|
|
||||||
|
void xfrm_flush_gc(void);
|
||||||
void xfrm_state_delete_tunnel(struct xfrm_state *x);
|
void xfrm_state_delete_tunnel(struct xfrm_state *x);
|
||||||
|
|
||||||
struct xfrm_type {
|
struct xfrm_type {
|
||||||
|
@ -669,7 +669,7 @@ static void vti6_link_config(struct ip6_tnl *t, bool keep_mtu)
|
|||||||
else
|
else
|
||||||
mtu = ETH_DATA_LEN - LL_MAX_HEADER - sizeof(struct ipv6hdr);
|
mtu = ETH_DATA_LEN - LL_MAX_HEADER - sizeof(struct ipv6hdr);
|
||||||
|
|
||||||
dev->mtu = max_t(int, mtu, IPV6_MIN_MTU);
|
dev->mtu = max_t(int, mtu, IPV4_MIN_MTU);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -881,7 +881,7 @@ static void vti6_dev_setup(struct net_device *dev)
|
|||||||
dev->priv_destructor = vti6_dev_free;
|
dev->priv_destructor = vti6_dev_free;
|
||||||
|
|
||||||
dev->type = ARPHRD_TUNNEL6;
|
dev->type = ARPHRD_TUNNEL6;
|
||||||
dev->min_mtu = IPV6_MIN_MTU;
|
dev->min_mtu = IPV4_MIN_MTU;
|
||||||
dev->max_mtu = IP_MAX_MTU - sizeof(struct ipv6hdr);
|
dev->max_mtu = IP_MAX_MTU - sizeof(struct ipv6hdr);
|
||||||
dev->flags |= IFF_NOARP;
|
dev->flags |= IFF_NOARP;
|
||||||
dev->addr_len = sizeof(struct in6_addr);
|
dev->addr_len = sizeof(struct in6_addr);
|
||||||
|
@ -341,6 +341,9 @@ static void __net_exit xfrm6_tunnel_net_exit(struct net *net)
|
|||||||
struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
|
struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
xfrm_state_flush(net, IPSEC_PROTO_ANY, false);
|
||||||
|
xfrm_flush_gc();
|
||||||
|
|
||||||
for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
|
for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
|
||||||
WARN_ON_ONCE(!hlist_empty(&xfrm6_tn->spi_byaddr[i]));
|
WARN_ON_ONCE(!hlist_empty(&xfrm6_tn->spi_byaddr[i]));
|
||||||
|
|
||||||
|
@ -437,6 +437,24 @@ static int verify_address_len(const void *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int sadb_key_len(const struct sadb_key *key)
|
||||||
|
{
|
||||||
|
int key_bytes = DIV_ROUND_UP(key->sadb_key_bits, 8);
|
||||||
|
|
||||||
|
return DIV_ROUND_UP(sizeof(struct sadb_key) + key_bytes,
|
||||||
|
sizeof(uint64_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int verify_key_len(const void *p)
|
||||||
|
{
|
||||||
|
const struct sadb_key *key = p;
|
||||||
|
|
||||||
|
if (sadb_key_len(key) > key->sadb_key_len)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx)
|
static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx)
|
||||||
{
|
{
|
||||||
return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) +
|
return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) +
|
||||||
@ -533,16 +551,25 @@ static int parse_exthdrs(struct sk_buff *skb, const struct sadb_msg *hdr, void *
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ext_hdrs[ext_type-1] != NULL)
|
if (ext_hdrs[ext_type-1] != NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ext_type == SADB_EXT_ADDRESS_SRC ||
|
switch (ext_type) {
|
||||||
ext_type == SADB_EXT_ADDRESS_DST ||
|
case SADB_EXT_ADDRESS_SRC:
|
||||||
ext_type == SADB_EXT_ADDRESS_PROXY ||
|
case SADB_EXT_ADDRESS_DST:
|
||||||
ext_type == SADB_X_EXT_NAT_T_OA) {
|
case SADB_EXT_ADDRESS_PROXY:
|
||||||
|
case SADB_X_EXT_NAT_T_OA:
|
||||||
if (verify_address_len(p))
|
if (verify_address_len(p))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
break;
|
||||||
if (ext_type == SADB_X_EXT_SEC_CTX) {
|
case SADB_X_EXT_SEC_CTX:
|
||||||
if (verify_sec_ctx_len(p))
|
if (verify_sec_ctx_len(p))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
break;
|
||||||
|
case SADB_EXT_KEY_AUTH:
|
||||||
|
case SADB_EXT_KEY_ENCRYPT:
|
||||||
|
if (verify_key_len(p))
|
||||||
|
return -EINVAL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ext_hdrs[ext_type-1] = (void *) p;
|
ext_hdrs[ext_type-1] = (void *) p;
|
||||||
}
|
}
|
||||||
@ -1104,14 +1131,12 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
|
|||||||
key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
|
key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
|
||||||
if (key != NULL &&
|
if (key != NULL &&
|
||||||
sa->sadb_sa_auth != SADB_X_AALG_NULL &&
|
sa->sadb_sa_auth != SADB_X_AALG_NULL &&
|
||||||
((key->sadb_key_bits+7) / 8 == 0 ||
|
key->sadb_key_bits == 0)
|
||||||
(key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
|
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1];
|
key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1];
|
||||||
if (key != NULL &&
|
if (key != NULL &&
|
||||||
sa->sadb_sa_encrypt != SADB_EALG_NULL &&
|
sa->sadb_sa_encrypt != SADB_EALG_NULL &&
|
||||||
((key->sadb_key_bits+7) / 8 == 0 ||
|
key->sadb_key_bits == 0)
|
||||||
(key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
|
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
x = xfrm_state_alloc(net);
|
x = xfrm_state_alloc(net);
|
||||||
|
@ -2175,6 +2175,12 @@ struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
|
|||||||
return afinfo;
|
return afinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xfrm_flush_gc(void)
|
||||||
|
{
|
||||||
|
flush_work(&xfrm_state_gc_work);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(xfrm_flush_gc);
|
||||||
|
|
||||||
/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
|
/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
|
||||||
void xfrm_state_delete_tunnel(struct xfrm_state *x)
|
void xfrm_state_delete_tunnel(struct xfrm_state *x)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user