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>
---
 drivers/net/vxlan.c | 10 +++++-----
 include/net/vxlan.h |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index b04e103..96aa7e6 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1034,11 +1034,11 @@ static bool vxlan_group_used(struct vxlan_net *vn, 
struct vxlan_dev *dev)
        /* The vxlan_sock is only used by dev, leaving group has
         * no effect on other vxlan devices.
         */
-       if (family == AF_INET && sock4 && atomic_read(&sock4->refcnt) == 1)
+       if (family == AF_INET && sock4 && refcount_read(&sock4->refcnt) == 1)
                return false;
 #if IS_ENABLED(CONFIG_IPV6)
        sock6 = rtnl_dereference(dev->vn6_sock);
-       if (family == AF_INET6 && sock6 && atomic_read(&sock6->refcnt) == 1)
+       if (family == AF_INET6 && sock6 && refcount_read(&sock6->refcnt) == 1)
                return false;
 #endif
 
@@ -1075,7 +1075,7 @@ static bool __vxlan_sock_release_prep(struct vxlan_sock 
*vs)
 
        if (!vs)
                return false;
-       if (!atomic_dec_and_test(&vs->refcnt))
+       if (!refcount_dec_and_test(&vs->refcnt))
                return false;
 
        vn = net_generic(sock_net(vs->sock->sk), vxlan_net_id);
@@ -2825,7 +2825,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net 
*net, bool ipv6,
        }
 
        vs->sock = sock;
-       atomic_set(&vs->refcnt, 1);
+       refcount_set(&vs->refcnt, 1);
        vs->flags = (flags & VXLAN_F_RCV_FLAGS);
 
        spin_lock(&vn->sock_lock);
@@ -2860,7 +2860,7 @@ static int __vxlan_sock_add(struct vxlan_dev *vxlan, bool 
ipv6)
                spin_lock(&vn->sock_lock);
                vs = vxlan_find_sock(vxlan->net, ipv6 ? AF_INET6 : AF_INET,
                                     vxlan->cfg.dst_port, vxlan->cfg.flags);
-               if (vs && !atomic_add_unless(&vs->refcnt, 1, 0)) {
+               if (vs && !refcount_inc_not_zero(&vs->refcnt)) {
                        spin_unlock(&vn->sock_lock);
                        return -EBUSY;
                }
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 326e849..3f430e3 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -183,7 +183,7 @@ struct vxlan_sock {
        struct hlist_node hlist;
        struct socket    *sock;
        struct hlist_head vni_list[VNI_HASH_SIZE];
-       atomic_t          refcnt;
+       refcount_t        refcnt;
        u32               flags;
 };
 
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-hams" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to