How to fix the bug in "WARNING: kobject bug in erofs_unregister_sysfs"?
Gao Xiang
hsiangkao at linux.alibaba.com
Fri Mar 11 15:56:38 AEDT 2022
On Fri, Mar 11, 2022 at 12:08:43PM +0800, Dongliang Mu wrote:
> On Thu, Mar 10, 2022 at 10:04 PM Dongliang Mu <mudongliangabcd at gmail.com> wrote:
> >
> > On Thu, Mar 10, 2022 at 8:39 PM Gao Xiang <hsiangkao at linux.alibaba.com> wrote:
> > >
> > > Hi Dongliang,
> > >
> > > (+ cc Jianan.)
> > >
> > > On Thu, Mar 10, 2022 at 06:15:20PM +0800, Dongliang Mu wrote:
> > > > Hi kernel developers,
> > > >
> > > > I am writing to kindly ask for some suggestions on fixing "WARNING:
> > > > kobject bug in erofs_unregister_sysfs".
> > > >
> > > > The underlying issue is in the following,
> > > >
> > > > erofs_fc_get_tree
> > > > -> get_tree_bdev
> > > > -> fill_super
> > > > -> erofs_fc_fill_super
> > > >
> > >
> > > Thanks for the report!
> > >
> > > > When erofs_register_sysfs fails in the calling kobject_init_and_add,
> > > > it just returned an error code and the parent function will call
> > > > deactivate_locked_super to do clean up.
> > >
> > > Yes, in that way we don't need to rewrite another error path (actually
> > > once we had another duplicated error path but Al suggested the current
> > > shape...)
> > >
> > > >
> > > > In the following stack trace, it finally calls erofs_unregister_sysfs
> > > > without knowing the execution status of erofs_register_sysfs, which
> > > > leads to the kobject bug.
> > > >
> > > > erofs_unregister_sysfs+0x46/0x60 fs/erofs/sysfs.c:225
> > > > erofs_put_super+0x37/0xb0 fs/erofs/super.c:771
> > > > generic_shutdown_super+0x14c/0x400 fs/super.c:465
> > > > kill_block_super+0x97/0xf0 fs/super.c:1397
> > > > erofs_kill_sb+0x60/0x190 fs/erofs/super.c:752
> > > > deactivate_locked_super+0x94/0x160 fs/super.c:335
> > > > get_tree_bdev+0x573/0x760 fs/super.c:1297
> > > >
> > > > I am not sure how to fix this bug. Any suggestion is appreciated.
> > >
> > > I think a simple way is to introduce a `sysfs_inited' boolean to
> > > sbi to indicate that. Or some better suggestion is welcomed.
> >
> > Yes, it's an idea to use a boolean to indicate the execution status.
> > Let me first try to craft a drafted patch and test it on Syzbot.
>
> I've drafted one patch and sent it here.
>
> diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
> index 5aa2cf2c2f80..ba2db2e9e3b7 100644
> --- a/fs/erofs/internal.h
> +++ b/fs/erofs/internal.h
> @@ -144,6 +144,7 @@ struct erofs_sb_info {
> u32 feature_incompat;
>
> /* sysfs support */
> + bool sysfs_inited;
bool s_sysfs_inited; ?
> struct kobject s_kobj; /* /sys/fs/erofs/<devname> */
> struct completion s_kobj_unregister;
> };
> diff --git a/fs/erofs/sysfs.c b/fs/erofs/sysfs.c
> index dac252bc9228..795273c15c42 100644
> --- a/fs/erofs/sysfs.c
> +++ b/fs/erofs/sysfs.c
> @@ -209,6 +209,7 @@ int erofs_register_sysfs(struct super_block *sb)
> "%s", sb->s_id);
> if (err)
> goto put_sb_kobj;
> + sbi->sysfs_inited = true;
> return 0;
>
> put_sb_kobj:
> @@ -221,8 +222,11 @@ void erofs_unregister_sysfs(struct super_block *sb)
> {
> struct erofs_sb_info *sbi = EROFS_SB(sb);
>
> - kobject_del(&sbi->s_kobj);
> - kobject_put(&sbi->s_kobj);
> + if (sbi->sysfs_inited) {
> + kobject_del(&sbi->s_kobj);
> + kobject_put(&sbi->s_kobj);
> + sbi->sysfs_inited = false;
> + }
> wait_for_completion(&sbi->s_kobj_unregister);
> }
>
> The compilation is fine. However, since the crash report does not have
> any reproducer, I cannot test it in Syzbot or my local instance.
>
Thanks for the patch. I think you could do some fault injection (e.g.
return err forcely in erofs_register_sysfs() ) to verify that.
If possible, would you mind submitting a formal patch then?
Thanks,
Gao Xiang
> >
> > >
> > > Thanks,
> > > Gao Xiang
> > >
> > > >
> > > > --
> > > > My best regards to you.
> > > >
> > > > No System Is Safe!
> > > > Dongliang Mu
More information about the Linux-erofs
mailing list