Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -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;
#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
+1 −1
Original line number Original line Diff line number Diff line
@@ -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;
}
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -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)
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);
}
}