Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
authorDavid S. Miller <davem@davemloft.net>
Tue, 23 May 2017 14:51:32 +0000 (10:51 -0400)
committerDavid S. Miller <davem@davemloft.net>
Tue, 23 May 2017 14:51:32 +0000 (10:51 -0400)
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>
include/net/xfrm.h
net/ipv4/esp4.c
net/key/af_key.c
net/xfrm/xfrm_device.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c

index 6793a30c66b1f054516a27229c29037fcdfa2f6f..7e7e2b0d29157047fa0d3596b3f97cf501d754f9 100644 (file)
@@ -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
 
index 65cc02bd82bc87991a29135a58c059c7916a5a35..93322f895eab6136adbe22aa37a4eedc9687a0e4 100644 (file)
@@ -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);
index c1950bb14735bc914b53c0476342f2679ad50b87..512dc43d0ce6814f0a6d0507805025d75234eece 100644 (file)
@@ -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;
                }
index 8ec8a3fcf8d4740670b16c2c1af099ef0beaa5c5..574e6f32f94f29a496ef20f1a673a0e718a1a31b 100644 (file)
@@ -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));
index b00a1d5a7f52e54f2ac454da3eeb14447f84d8b2..ed4e52d95172e2d8dcca603cdf62cfb55517f3c9 100644 (file)
@@ -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);
index fc3c5aa387543a63bf18955e60309207bf06e961..2e291bc5f1fc1003ca62e40f67da8a6a46875c02 100644 (file)
@@ -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;