net: convert net.passive from atomic_t to refcount_t
authorReshetova, Elena <elena.reshetova@intel.com>
Fri, 30 Jun 2017 10:08:08 +0000 (13:08 +0300)
committerDavid S. Miller <davem@davemloft.net>
Sat, 1 Jul 2017 14:39:09 +0000 (07:39 -0700)
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/net_namespace.h
net/core/net-sysfs.c
net/core/net_namespace.c

index a24a57593202456dd3e25ce1891f70c33ccd7ffe..31a2b51bef2c8f05a68f3d6ff3923d94a77592f8 100644 (file)
@@ -5,6 +5,7 @@
 #define __NET_NET_NAMESPACE_H
 
 #include <linux/atomic.h>
+#include <linux/refcount.h>
 #include <linux/workqueue.h>
 #include <linux/list.h>
 #include <linux/sysctl.h>
@@ -46,7 +47,7 @@ struct netns_ipvs;
 #define NETDEV_HASHENTRIES (1 << NETDEV_HASHBITS)
 
 struct net {
-       atomic_t                passive;        /* To decided when the network
+       refcount_t              passive;        /* To decided when the network
                                                 * namespace should be freed.
                                                 */
        atomic_t                count;          /* To decided when the network
index fe7e145c543c6af0b9f46a48b75ad87e5267ec9d..b4f9922b6f233da3d4a189b80b12034f6f7fddeb 100644 (file)
@@ -1448,7 +1448,7 @@ static void *net_grab_current_ns(void)
        struct net *ns = current->nsproxy->net_ns;
 #ifdef CONFIG_NET_NS
        if (ns)
-               atomic_inc(&ns->passive);
+               refcount_inc(&ns->passive);
 #endif
        return ns;
 }
index 6a2f412882494fa8ec571370648719ab7b4b5265..8726d051f31dd2ddce96a8cd7b1ccf50435f0d92 100644 (file)
@@ -284,7 +284,7 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
        LIST_HEAD(net_exit_list);
 
        atomic_set(&net->count, 1);
-       atomic_set(&net->passive, 1);
+       refcount_set(&net->passive, 1);
        net->dev_base_seq = 1;
        net->user_ns = user_ns;
        idr_init(&net->netns_ids);
@@ -380,7 +380,7 @@ static void net_free(struct net *net)
 void net_drop_ns(void *p)
 {
        struct net *ns = p;
-       if (ns && atomic_dec_and_test(&ns->passive))
+       if (ns && refcount_dec_and_test(&ns->passive))
                net_free(ns);
 }