Skip to content

Commit 768e4bb

Browse files
q2vendavem330
authored andcommitted
net: Don't register pernet_operations if only one of id or size is specified.
We can allocate per-netns memory for struct pernet_operations by specifying id and size. register_pernet_operations() assigns an id to pernet_operations and later ops_init() allocates the specified size of memory as net->gen->ptr[id]. If id is missing, no memory is allocated. If size is not specified, pernet_operations just wastes an entry of net->gen->ptr[] for every netns. net_generic is available only when both id and size are specified, so let's ensure that. While we are at it, we add const to both fields. Signed-off-by: Kuniyuki Iwashima <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1ad0013 commit 768e4bb

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

include/net/net_namespace.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,8 @@ struct pernet_operations {
451451
/* Following method is called with RTNL held. */
452452
void (*exit_batch_rtnl)(struct list_head *net_exit_list,
453453
struct list_head *dev_kill_list);
454-
unsigned int *id;
455-
size_t size;
454+
unsigned int * const id;
455+
const size_t size;
456456
};
457457

458458
/*

net/core/net_namespace.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ static int ops_init(const struct pernet_operations *ops, struct net *net)
125125
int err = -ENOMEM;
126126
void *data = NULL;
127127

128-
if (ops->id && ops->size) {
128+
if (ops->id) {
129129
data = kzalloc(ops->size, GFP_KERNEL);
130130
if (!data)
131131
goto out;
@@ -140,7 +140,7 @@ static int ops_init(const struct pernet_operations *ops, struct net *net)
140140
if (!err)
141141
return 0;
142142

143-
if (ops->id && ops->size) {
143+
if (ops->id) {
144144
ng = rcu_dereference_protected(net->gen,
145145
lockdep_is_held(&pernet_ops_rwsem));
146146
ng->ptr[*ops->id] = NULL;
@@ -182,7 +182,8 @@ static void ops_free_list(const struct pernet_operations *ops,
182182
struct list_head *net_exit_list)
183183
{
184184
struct net *net;
185-
if (ops->size && ops->id) {
185+
186+
if (ops->id) {
186187
list_for_each_entry(net, net_exit_list, exit_list)
187188
kfree(net_generic(net, *ops->id));
188189
}
@@ -1244,7 +1245,7 @@ static int __register_pernet_operations(struct list_head *list,
12441245
LIST_HEAD(net_exit_list);
12451246

12461247
list_add_tail(&ops->list, list);
1247-
if (ops->init || (ops->id && ops->size)) {
1248+
if (ops->init || ops->id) {
12481249
/* We held write locked pernet_ops_rwsem, and parallel
12491250
* setup_net() and cleanup_net() are not possible.
12501251
*/
@@ -1310,6 +1311,9 @@ static int register_pernet_operations(struct list_head *list,
13101311
{
13111312
int error;
13121313

1314+
if (WARN_ON(!!ops->id ^ !!ops->size))
1315+
return -EINVAL;
1316+
13131317
if (ops->id) {
13141318
error = ida_alloc_min(&net_generic_ids, MIN_PERNET_OPS_ID,
13151319
GFP_KERNEL);

0 commit comments

Comments
 (0)