diff options
| -rw-r--r-- | net/core/net_namespace.c | 13 | 
1 files changed, 10 insertions, 3 deletions
| diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index f0540c557515..9d690d32da33 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -69,12 +69,15 @@ DEFINE_COOKIE(net_cookie);  static struct net_generic *net_alloc_generic(void)  { +	unsigned int gen_ptrs = READ_ONCE(max_gen_ptrs); +	unsigned int generic_size;  	struct net_generic *ng; -	unsigned int generic_size = offsetof(struct net_generic, ptr[max_gen_ptrs]); + +	generic_size = offsetof(struct net_generic, ptr[gen_ptrs]);  	ng = kzalloc(generic_size, GFP_KERNEL);  	if (ng) -		ng->s.len = max_gen_ptrs; +		ng->s.len = gen_ptrs;  	return ng;  } @@ -1307,7 +1310,11 @@ static int register_pernet_operations(struct list_head *list,  		if (error < 0)  			return error;  		*ops->id = error; -		max_gen_ptrs = max(max_gen_ptrs, *ops->id + 1); +		/* This does not require READ_ONCE as writers already hold +		 * pernet_ops_rwsem. But WRITE_ONCE is needed to protect +		 * net_alloc_generic. +		 */ +		WRITE_ONCE(max_gen_ptrs, max(max_gen_ptrs, *ops->id + 1));  	}  	error = __register_pernet_operations(list, ops);  	if (error) { |