forked from Minki/linux
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
Steffen Klassert says: ==================== pull request (net): ipsec 2017-05-23 1) Fix wrong header offset for esp4 udpencap packets. 2) Fix a stack access out of bounds when creating a bundle with sub policies. From Sabrina Dubroca. 3) Fix slab-out-of-bounds in pfkey due to an incorrect sadb_x_sec_len calculation. 4) We checked the wrong feature flags when taking down an interface with IPsec offload enabled. Fix from Ilan Tayari. 5) Copy the anti replay sequence numbers when doing a state migration, otherwise we get out of sync with the sequence numbers. Fix from Antony Antony. Please pull or let me know if there are problems. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
2f9bfd3399
@ -979,10 +979,6 @@ struct xfrm_dst {
|
||||
struct flow_cache_object flo;
|
||||
struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
|
||||
int num_pols, num_xfrms;
|
||||
#ifdef CONFIG_XFRM_SUB_POLICY
|
||||
struct flowi *origin;
|
||||
struct xfrm_selector *partner;
|
||||
#endif
|
||||
u32 xfrm_genid;
|
||||
u32 policy_genid;
|
||||
u32 route_mtu_cached;
|
||||
@ -998,12 +994,6 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
|
||||
dst_release(xdst->route);
|
||||
if (likely(xdst->u.dst.xfrm))
|
||||
xfrm_state_put(xdst->u.dst.xfrm);
|
||||
#ifdef CONFIG_XFRM_SUB_POLICY
|
||||
kfree(xdst->origin);
|
||||
xdst->origin = NULL;
|
||||
kfree(xdst->partner);
|
||||
xdst->partner = NULL;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -248,6 +248,7 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
|
||||
u8 *tail;
|
||||
u8 *vaddr;
|
||||
int nfrags;
|
||||
int esph_offset;
|
||||
struct page *page;
|
||||
struct sk_buff *trailer;
|
||||
int tailen = esp->tailen;
|
||||
@ -313,11 +314,13 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
|
||||
}
|
||||
|
||||
cow:
|
||||
esph_offset = (unsigned char *)esp->esph - skb_transport_header(skb);
|
||||
|
||||
nfrags = skb_cow_data(skb, tailen, &trailer);
|
||||
if (nfrags < 0)
|
||||
goto out;
|
||||
tail = skb_tail_pointer(trailer);
|
||||
esp->esph = ip_esp_hdr(skb);
|
||||
esp->esph = (struct ip_esp_hdr *)(skb_transport_header(skb) + esph_offset);
|
||||
|
||||
skip_cow:
|
||||
esp_output_fill_trailer(tail, esp->tfclen, esp->plen, esp->proto);
|
||||
|
@ -3285,7 +3285,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
|
||||
p += pol->sadb_x_policy_len*8;
|
||||
sec_ctx = (struct sadb_x_sec_ctx *)p;
|
||||
if (len < pol->sadb_x_policy_len*8 +
|
||||
sec_ctx->sadb_x_sec_len) {
|
||||
sec_ctx->sadb_x_sec_len*8) {
|
||||
*dir = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ static int xfrm_dev_feat_change(struct net_device *dev)
|
||||
|
||||
static int xfrm_dev_down(struct net_device *dev)
|
||||
{
|
||||
if (dev->hw_features & NETIF_F_HW_ESP)
|
||||
if (dev->features & NETIF_F_HW_ESP)
|
||||
xfrm_dev_state_flush(dev_net(dev), dev, true);
|
||||
|
||||
xfrm_garbage_collect(dev_net(dev));
|
||||
|
@ -1797,43 +1797,6 @@ free_dst:
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XFRM_SUB_POLICY
|
||||
static int xfrm_dst_alloc_copy(void **target, const void *src, int size)
|
||||
{
|
||||
if (!*target) {
|
||||
*target = kmalloc(size, GFP_ATOMIC);
|
||||
if (!*target)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(*target, src, size);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int xfrm_dst_update_parent(struct dst_entry *dst,
|
||||
const struct xfrm_selector *sel)
|
||||
{
|
||||
#ifdef CONFIG_XFRM_SUB_POLICY
|
||||
struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
|
||||
return xfrm_dst_alloc_copy((void **)&(xdst->partner),
|
||||
sel, sizeof(*sel));
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int xfrm_dst_update_origin(struct dst_entry *dst,
|
||||
const struct flowi *fl)
|
||||
{
|
||||
#ifdef CONFIG_XFRM_SUB_POLICY
|
||||
struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
|
||||
return xfrm_dst_alloc_copy((void **)&(xdst->origin), fl, sizeof(*fl));
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int xfrm_expand_policies(const struct flowi *fl, u16 family,
|
||||
struct xfrm_policy **pols,
|
||||
int *num_pols, int *num_xfrms)
|
||||
@ -1905,16 +1868,6 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
|
||||
|
||||
xdst = (struct xfrm_dst *)dst;
|
||||
xdst->num_xfrms = err;
|
||||
if (num_pols > 1)
|
||||
err = xfrm_dst_update_parent(dst, &pols[1]->selector);
|
||||
else
|
||||
err = xfrm_dst_update_origin(dst, fl);
|
||||
if (unlikely(err)) {
|
||||
dst_free(dst);
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
xdst->num_pols = num_pols;
|
||||
memcpy(xdst->pols, pols, sizeof(struct xfrm_policy *) * num_pols);
|
||||
xdst->policy_genid = atomic_read(&pols[0]->genid);
|
||||
|
@ -1383,6 +1383,8 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig)
|
||||
x->curlft.add_time = orig->curlft.add_time;
|
||||
x->km.state = orig->km.state;
|
||||
x->km.seq = orig->km.seq;
|
||||
x->replay = orig->replay;
|
||||
x->preplay = orig->preplay;
|
||||
|
||||
return x;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user