Skip to content

Commit 1a9a059

Browse files
Alexey Dobriyandavem330
authored andcommitted
netns: publish net_generic correctly
Publishing net_generic pointer is done with silly mistake: new array is published BEFORE setting freshly acquired pernet subsystem pointer. memcpy rcu_assign_pointer kfree_rcu ng->ptr[id - 1] = data; This bug was introduced with commit dec827d ("[NETNS]: The generic per-net pointers.") in the glorious days of chopping networking stack into containers proper 8.5 years ago (whee...) How it didn't trigger for so long? Well, you need quite specific set of conditions: *) race window opens once per pernet subsystem addition (read: modprobe or boot) *) not every pernet subsystem is eligible (need ->id and ->size) *) not every pernet subsystem is vulnerable (need incorrect or absense of ordering of register_pernet_sybsys() and actually using net_generic()) *) to hide the bug even more, default is to preallocate 13 pointers which is actually quite a lot. You need IPv6, netfilter, bridging etc together loaded to trigger reallocation in the first place. Trimmed down config are OK. Signed-off-by: Alexey Dobriyan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4f7df33 commit 1a9a059

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

net/core/net_namespace.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ static int net_assign_generic(struct net *net, unsigned int id, void *data)
6464

6565
old_ng = rcu_dereference_protected(net->gen,
6666
lockdep_is_held(&net_mutex));
67-
ng = old_ng;
68-
if (old_ng->len >= id)
69-
goto assign;
67+
if (old_ng->len >= id) {
68+
old_ng->ptr[id - 1] = data;
69+
return 0;
70+
}
7071

7172
ng = net_alloc_generic();
7273
if (ng == NULL)
@@ -84,11 +85,10 @@ static int net_assign_generic(struct net *net, unsigned int id, void *data)
8485
*/
8586

8687
memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*));
88+
ng->ptr[id - 1] = data;
8789

8890
rcu_assign_pointer(net->gen, ng);
8991
kfree_rcu(old_ng, rcu);
90-
assign:
91-
ng->ptr[id - 1] = data;
9292
return 0;
9393
}
9494

0 commit comments

Comments
 (0)