From: Sanan Hasanov Commit 8a4cf500f1dd ("dlm: drop kobject release callback handling") dropped the do_unreg flag from new_lockspace() and made the out_lsfree error label call kobject_put(&ls->ls_kobj) unconditionally. But ls_kobj is only initialized by kobject_init_and_add() after the callback workqueue and dlm_recoverd have been started, so every failure before that point puts a kobject that was never initialized: dlm: ls_6035_1: can't start dlm_callback -12 kobject: '(null)' (ffff888027a28088): is not initialized, yet kobject_put() is being called. WARNING: lib/kobject.c:736 at kobject_put+0x66/0x550 lib/kobject.c:734 Call Trace: new_lockspace fs/dlm/lockspace.c:617 [inline] __dlm_new_lockspace+0x1714/0x1cd0 fs/dlm/lockspace.c:638 device_create_lockspace+0xc7/0x350 fs/dlm/user.c:414 device_write+0x872/0xed0 fs/dlm/user.c:606 vfs_write+0x296/0xba0 fs/read_write.c:685 syzbot hits this by sending SIGKILL to a task creating a lockspace through /dev/dlm-control, so that alloc_ordered_workqueue() in dlm_callback_start() fails to create its rescuer thread. The same happens if rhashtable_init(), the ls_recover_buf allocation or dlm_recoverd_start() fail. Bring the flag back so the kobject is only put once kobject_init_and_add() has been called. Since the kobject no longer frees the lockspace, kfree(ls) still runs on every error path. Fixes: 8a4cf500f1dd ("dlm: drop kobject release callback handling") Reported-by: syzbot+b2b8d04ec4914f618d23@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=b2b8d04ec4914f618d23 Cc: stable@vger.kernel.org Signed-off-by: Sanan Hasanov --- fs/dlm/lockspace.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index a9c98b4f37..443421e945 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -364,6 +364,7 @@ static int new_lockspace(const char *name, const char *cluster, int *ops_result, dlm_lockspace_t **lockspace) { struct dlm_ls *ls; + int do_unreg = 0; int namelen = strlen(name); int error; @@ -567,6 +568,9 @@ static int new_lockspace(const char *name, const char *cluster, wait_event(ls->ls_recover_lock_wait, test_bit(LSFL_RECOVER_LOCK, &ls->ls_flags)); + /* ls_kobj must only be put once kobject_init_and_add() ran */ + do_unreg = 1; + ls->ls_kobj.kset = dlm_kset; error = kobject_init_and_add(&ls->ls_kobj, &dlm_ktype, NULL, "%s", ls->ls_name); @@ -614,7 +618,8 @@ static int new_lockspace(const char *name, const char *cluster, xa_destroy(&ls->ls_lkbxa); rhashtable_destroy(&ls->ls_rsbtbl); out_lsfree: - kobject_put(&ls->ls_kobj); + if (do_unreg) + kobject_put(&ls->ls_kobj); kfree(ls); out: module_put(THIS_MODULE); -- 2.34.1