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.reshet...@intel.com>
Signed-off-by: Hans Liljestrand <ishkam...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Signed-off-by: David Windsor <dwind...@gmail.com>
---
 include/net/xfrm.h     | 6 +++---
 net/key/af_key.c       | 2 +-
 net/xfrm/xfrm_policy.c | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index f5272a2..e1bd1de 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -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);
 }
 
diff --git a/net/key/af_key.c b/net/key/af_key.c
index edcf1d0..ca9d3ae 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -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;
 }
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 4706df6..ff61d85 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -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);
-- 
2.7.4

Reply via email to