History

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec

Steffen Klassert says: ==================== pull request (net): ipsec 2018-12-18 1) Fix error return code in xfrm_output_one() when no dst_entry is attached to the skb. From Wei Yongjun. 2) The xfrm state hash bucket count reported to userspace is off by one. Fix from Benjamin Poirier. 3) Fix NULL pointer dereference in xfrm_input when skb_dst_force clears the dst_entry. 4) Fix freeing of xfrm states on acquire. We use a dedicated slab cache for the xfrm states now, so free it properly with kmem_cache_free. From Mathias Krause. Please pull or let me know if there are problems. ====================

David S. Miller committed 7 years ago

Commit fde9cd62 parents 8d013b7 4a135e55 files · +18 −5Browse files

Unified · Split

5 files
  1. include/net/xfrm.h +1 −0
  2. net/xfrm/xfrm_input.c +6 −1
  3. net/xfrm/xfrm_output.c +1 −0
  4. net/xfrm/xfrm_state.c +8 −2
  5. net/xfrm/xfrm_user.c +2 −2
include/net/xfrm.h+1−0
@@ -1552,6 +1552,7 @@ int xfrm_state_walk(struct net *net, struct xfrm_state_walk *walk, · 1551 unmodified lines
15521552 int (*func)(struct xfrm_state *, int, void*), void *);
15531553 void xfrm_state_walk_done(struct xfrm_state_walk *walk, struct net *net);
15541554 struct xfrm_state *xfrm_state_alloc(struct net *net);
1555+void xfrm_state_free(struct xfrm_state *x);
15551556 struct xfrm_state *xfrm_state_find(const xfrm_address_t *daddr,
15561557 const xfrm_address_t *saddr,
15571558 const struct flowi *fl,
net/xfrm/xfrm_input.c+6−1
@@ -346,6 +346,12 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) · 345 unmodified lines
346346
347347 skb->sp->xvec[skb->sp->len++] = x;
348348
349+ skb_dst_force(skb);
350+ if (!skb_dst(skb)) {
351+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR);
352+ goto drop;
353+ }
354+
349355 lock:
350356 spin_lock(&x->lock);
351357
@@ -385,7 +391,6 @@ lock: · 33 unmodified lines
385391 XFRM_SKB_CB(skb)->seq.input.low = seq;
386392 XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
387393
388− skb_dst_force(skb);
389394 dev_hold(skb->dev);
390395
391396 if (crypto_done)
net/xfrm/xfrm_output.c+1−0
@@ -102,6 +102,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err) · 101 unmodified lines
102102 skb_dst_force(skb);
103103 if (!skb_dst(skb)) {
104104 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
105+ err = -EHOSTUNREACH;
105106 goto error_nolock;
106107 }
107108
net/xfrm/xfrm_state.c+8−2
@@ -426,6 +426,12 @@ static void xfrm_put_mode(struct xfrm_mode *mode) · 425 unmodified lines
426426 module_put(mode->owner);
427427 }
428428
429+void xfrm_state_free(struct xfrm_state *x)
430+{
431+ kmem_cache_free(xfrm_state_cache, x);
432+}
433+EXPORT_SYMBOL(xfrm_state_free);
434+
429435 static void xfrm_state_gc_destroy(struct xfrm_state *x)
430436 {
431437 tasklet_hrtimer_cancel(&x->mtimer);
@@ -452,7 +458,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) · 20 unmodified lines
452458 }
453459 xfrm_dev_state_free(x);
454460 security_xfrm_state_free(x);
455− kmem_cache_free(xfrm_state_cache, x);
461+ xfrm_state_free(x);
456462 }
457463
458464 static void xfrm_state_gc_task(struct work_struct *work)
@@ -788,7 +794,7 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si) · 329 unmodified lines
788794 {
789795 spin_lock_bh(&net->xfrm.xfrm_state_lock);
790796 si->sadcnt = net->xfrm.state_num;
791− si->sadhcnt = net->xfrm.state_hmask;
797+ si->sadhcnt = net->xfrm.state_hmask + 1;
792798 si->sadhmcnt = xfrm_state_hashmax;
793799 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
794800 }
net/xfrm/xfrm_user.c+2−2
@@ -2288,13 +2288,13 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, · 2287 unmodified lines
22882288
22892289 }
22902290
2291− kfree(x);
2291+ xfrm_state_free(x);
22922292 kfree(xp);
22932293
22942294 return 0;
22952295
22962296 free_state:
2297− kfree(x);
2297+ xfrm_state_free(x);
22982298 nomem:
22992299 return err;
23002300 }