net, xfrm: convert xfrm_policy.refcnt from atomic_t to refcount_t
authorReshetova, Elena <elena.reshetova@intel.com>
Tue, 4 Jul 2017 12:53:22 +0000 (15:53 +0300)
committerDavid S. Miller <davem@davemloft.net>
Tue, 4 Jul 2017 21:35:18 +0000 (22:35 +0100)
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.

Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/xfrm.h
net/key/af_key.c
net/xfrm/xfrm_policy.c

index f5272a275e8f3c83601e23122bc78ba1456b4cce..e1bd1de2d66ac9f06961e6bf1b5bb3736ed4c13e 100644 (file)
@@ -560,7 +560,7 @@ struct xfrm_policy {
 
        /* This lock only affects elements except for entry. */
        rwlock_t                lock;
-       atomic_t                refcnt;
+       refcount_t              refcnt;
        struct timer_list       timer;
 
        struct flow_cache_object flo;
@@ -816,14 +816,14 @@ static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
 static inline void xfrm_pol_hold(struct xfrm_policy *policy)
 {
        if (likely(policy != NULL))
-               atomic_inc(&policy->refcnt);
+               refcount_inc(&policy->refcnt);
 }
 
 void xfrm_policy_destroy(struct xfrm_policy *policy);
 
 static inline void xfrm_pol_put(struct xfrm_policy *policy)
 {
-       if (atomic_dec_and_test(&policy->refcnt))
+       if (refcount_dec_and_test(&policy->refcnt))
                xfrm_policy_destroy(policy);
 }
 
index edcf1d0f82c80bab61fbf93fb962c52c9360baad..ca9d3ae665e76ea847a4ce03b4d275f80d7705bc 100644 (file)
@@ -2177,7 +2177,7 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, const struct xfrm_policy *
        }
 
        hdr->sadb_msg_len = size / sizeof(uint64_t);
-       hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
+       hdr->sadb_msg_reserved = refcount_read(&xp->refcnt);
 
        return 0;
 }
index 4706df61217052d63868416072d15e12344acc03..ff61d85579292dee8a7f1e9926e11734556f4fd9 100644 (file)
@@ -62,7 +62,7 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
 
 static inline bool xfrm_pol_hold_rcu(struct xfrm_policy *policy)
 {
-       return atomic_inc_not_zero(&policy->refcnt);
+       return refcount_inc_not_zero(&policy->refcnt);
 }
 
 static inline bool
@@ -292,7 +292,7 @@ struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp)
                INIT_HLIST_NODE(&policy->bydst);
                INIT_HLIST_NODE(&policy->byidx);
                rwlock_init(&policy->lock);
-               atomic_set(&policy->refcnt, 1);
+               refcount_set(&policy->refcnt, 1);
                skb_queue_head_init(&policy->polq.hold_queue);
                setup_timer(&policy->timer, xfrm_policy_timer,
                                (unsigned long)policy);