Commit c122e14d authored by Reshetova, Elena's avatar Reshetova, Elena Committed by David S. Miller

net: convert net.passive from atomic_t to refcount_t

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: default avatarElena Reshetova <elena.reshetova@intel.com>
Signed-off-by: default avatarHans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarDavid Windsor <dwindsor@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent edcb6918
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#define __NET_NET_NAMESPACE_H #define __NET_NET_NAMESPACE_H
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/refcount.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
...@@ -46,7 +47,7 @@ struct netns_ipvs; ...@@ -46,7 +47,7 @@ struct netns_ipvs;
#define NETDEV_HASHENTRIES (1 << NETDEV_HASHBITS) #define NETDEV_HASHENTRIES (1 << NETDEV_HASHBITS)
struct net { struct net {
atomic_t passive; /* To decided when the network refcount_t passive; /* To decided when the network
* namespace should be freed. * namespace should be freed.
*/ */
atomic_t count; /* To decided when the network atomic_t count; /* To decided when the network
......
...@@ -1448,7 +1448,7 @@ static void *net_grab_current_ns(void) ...@@ -1448,7 +1448,7 @@ static void *net_grab_current_ns(void)
struct net *ns = current->nsproxy->net_ns; struct net *ns = current->nsproxy->net_ns;
#ifdef CONFIG_NET_NS #ifdef CONFIG_NET_NS
if (ns) if (ns)
atomic_inc(&ns->passive); refcount_inc(&ns->passive);
#endif #endif
return ns; return ns;
} }
......
...@@ -284,7 +284,7 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns) ...@@ -284,7 +284,7 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
LIST_HEAD(net_exit_list); LIST_HEAD(net_exit_list);
atomic_set(&net->count, 1); atomic_set(&net->count, 1);
atomic_set(&net->passive, 1); refcount_set(&net->passive, 1);
net->dev_base_seq = 1; net->dev_base_seq = 1;
net->user_ns = user_ns; net->user_ns = user_ns;
idr_init(&net->netns_ids); idr_init(&net->netns_ids);
...@@ -380,7 +380,7 @@ static void net_free(struct net *net) ...@@ -380,7 +380,7 @@ static void net_free(struct net *net)
void net_drop_ns(void *p) void net_drop_ns(void *p)
{ {
struct net *ns = p; struct net *ns = p;
if (ns && atomic_dec_and_test(&ns->passive)) if (ns && refcount_dec_and_test(&ns->passive))
net_free(ns); net_free(ns);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment