Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
authorDavid S. Miller <davem@davemloft.net>
Tue, 18 Dec 2018 19:43:26 +0000 (11:43 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 18 Dec 2018 19:43:26 +0000 (11:43 -0800)
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.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
1  2 
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c

diff --combined net/xfrm/xfrm_state.c
index dc4a9f1fb941a8eef7f1a3b68563c17abcf4d919,cc0203efb584b86199e801dbbb94b6f28d573988..23c92891758a829e06dd776baf7ca340dec67b9f
@@@ -426,6 -426,12 +426,12 @@@ static void xfrm_put_mode(struct xfrm_m
        module_put(mode->owner);
  }
  
+ void xfrm_state_free(struct xfrm_state *x)
+ {
+       kmem_cache_free(xfrm_state_cache, x);
+ }
+ EXPORT_SYMBOL(xfrm_state_free);
  static void xfrm_state_gc_destroy(struct xfrm_state *x)
  {
        tasklet_hrtimer_cancel(&x->mtimer);
        }
        xfrm_dev_state_free(x);
        security_xfrm_state_free(x);
-       kmem_cache_free(xfrm_state_cache, x);
+       xfrm_state_free(x);
  }
  
  static void xfrm_state_gc_task(struct work_struct *work)
@@@ -788,7 -794,7 +794,7 @@@ void xfrm_sad_getinfo(struct net *net, 
  {
        spin_lock_bh(&net->xfrm.xfrm_state_lock);
        si->sadcnt = net->xfrm.state_num;
-       si->sadhcnt = net->xfrm.state_hmask;
+       si->sadhcnt = net->xfrm.state_hmask + 1;
        si->sadhmcnt = xfrm_state_hashmax;
        spin_unlock_bh(&net->xfrm.xfrm_state_lock);
  }
@@@ -2077,8 -2083,10 +2083,8 @@@ int xfrm_user_policy(struct sock *sk, i
        struct xfrm_mgr *km;
        struct xfrm_policy *pol = NULL;
  
 -#ifdef CONFIG_COMPAT
        if (in_compat_syscall())
                return -EOPNOTSUPP;
 -#endif
  
        if (!optval && !optlen) {
                xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL);
diff --combined net/xfrm/xfrm_user.c
index c9a84e22f5d578216cd59687e293ed3a078cd565,683080172655fc6418b7a7ece9ad8e7b106de4e4..277c1c46fe94e17db85f20a4abe3bacae9a1f1b0
@@@ -2288,13 -2288,13 +2288,13 @@@ static int xfrm_add_acquire(struct sk_b
  
        }
  
-       kfree(x);
+       xfrm_state_free(x);
        kfree(xp);
  
        return 0;
  
  free_state:
-       kfree(x);
+       xfrm_state_free(x);
  nomem:
        return err;
  }
@@@ -2621,8 -2621,10 +2621,8 @@@ static int xfrm_user_rcv_msg(struct sk_
        const struct xfrm_link *link;
        int type, err;
  
 -#ifdef CONFIG_COMPAT
        if (in_compat_syscall())
                return -EOPNOTSUPP;
 -#endif
  
        type = nlh->nlmsg_type;
        if (type > XFRM_MSG_MAX)