Skip to content

Commit 6e77a5a

Browse files
edumazetkuba-moo
authored andcommitted
net: initialize net->notrefcnt_tracker earlier
syzbot was able to trigger a warning [1] from net_free() calling ref_tracker_dir_exit(&net->notrefcnt_tracker) while the corresponding ref_tracker_dir_init() has not been done yet. copy_net_ns() can indeed bypass the call to setup_net() in some error conditions. Note: We might factorize/move more code in preinit_net() in the future. [1] INFO: trying to register non-static key. The code is fine but needs lockdep annotation, or maybe you didn't initialize this object before use? turning off the locking correctness validator. CPU: 0 PID: 5817 Comm: syz-executor.3 Not tainted 6.2.0-rc7-next-20230208-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/12/2023 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xd9/0x150 lib/dump_stack.c:106 assign_lock_key kernel/locking/lockdep.c:982 [inline] register_lock_class+0xdb6/0x1120 kernel/locking/lockdep.c:1295 __lock_acquire+0x10a/0x5df0 kernel/locking/lockdep.c:4951 lock_acquire.part.0+0x11c/0x370 kernel/locking/lockdep.c:5691 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0x3d/0x60 kernel/locking/spinlock.c:162 ref_tracker_dir_exit+0x52/0x600 lib/ref_tracker.c:24 net_free net/core/net_namespace.c:442 [inline] net_free+0x98/0xd0 net/core/net_namespace.c:436 copy_net_ns+0x4f3/0x6b0 net/core/net_namespace.c:493 create_new_namespaces+0x3f6/0xb20 kernel/nsproxy.c:110 unshare_nsproxy_namespaces+0xc1/0x1f0 kernel/nsproxy.c:228 ksys_unshare+0x449/0x920 kernel/fork.c:3205 __do_sys_unshare kernel/fork.c:3276 [inline] __se_sys_unshare kernel/fork.c:3274 [inline] __x64_sys_unshare+0x31/0x40 kernel/fork.c:3274 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 Fixes: 0cafd77 ("net: add a refcount tracker for kernel sockets") Reported-by: syzbot <[email protected]> Signed-off-by: Eric Dumazet <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent e8ac615 commit 6e77a5a

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

net/core/net_namespace.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,12 @@ struct net *get_net_ns_by_id(const struct net *net, int id)
304304
}
305305
EXPORT_SYMBOL_GPL(get_net_ns_by_id);
306306

307+
/* init code that must occur even if setup_net() is not called. */
308+
static __net_init void preinit_net(struct net *net)
309+
{
310+
ref_tracker_dir_init(&net->notrefcnt_tracker, 128);
311+
}
312+
307313
/*
308314
* setup_net runs the initializers for the network namespace object.
309315
*/
@@ -316,7 +322,6 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns)
316322

317323
refcount_set(&net->ns.count, 1);
318324
ref_tracker_dir_init(&net->refcnt_tracker, 128);
319-
ref_tracker_dir_init(&net->notrefcnt_tracker, 128);
320325

321326
refcount_set(&net->passive, 1);
322327
get_random_bytes(&net->hash_mix, sizeof(u32));
@@ -472,6 +477,8 @@ struct net *copy_net_ns(unsigned long flags,
472477
rv = -ENOMEM;
473478
goto dec_ucounts;
474479
}
480+
481+
preinit_net(net);
475482
refcount_set(&net->passive, 1);
476483
net->ucounts = ucounts;
477484
get_user_ns(user_ns);
@@ -1118,6 +1125,7 @@ void __init net_ns_init(void)
11181125
init_net.key_domain = &init_net_key_domain;
11191126
#endif
11201127
down_write(&pernet_ops_rwsem);
1128+
preinit_net(&init_net);
11211129
if (setup_net(&init_net, &init_user_ns))
11221130
panic("Could not setup the initial network namespace");
11231131

0 commit comments

Comments
 (0)