Skip to content

Commit

Permalink
module: delay kobject uevent until after module init call
Browse files Browse the repository at this point in the history
[ Upstream commit 38dc717 ]

Apparently there has been a longstanding race between udev/systemd and
the module loader. Currently, the module loader sends a uevent right
after sysfs initialization, but before the module calls its init
function. However, some udev rules expect that the module has
initialized already upon receiving the uevent.

This race has been triggered recently (see link in references) in some
systemd mount unit files. For instance, the configfs module creates the
/sys/kernel/config mount point in its init function, however the module
loader issues the uevent before this happens. sys-kernel-config.mount
expects to be able to mount /sys/kernel/config upon receipt of the
module loading uevent, but if the configfs module has not called its
init function yet, then this directory will not exist and the mount unit
fails. A similar situation exists for sys-fs-fuse-connections.mount, as
the fuse sysfs mount point is created during the fuse module's init
function. If udev is faster than module initialization then the mount
unit would fail in a similar fashion.

To fix this race, delay the module KOBJ_ADD uevent until after the
module has finished calling its init routine.

References: https://github.com/systemd/systemd/issues/17586
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Tested-By: Nicolas Morey-Chaisemartin <nmoreychaisemartin@suse.com>
Signed-off-by: Jessica Yu <jeyu@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Jessica Yu authored and Greg Kroah-Hartman committed Jan 6, 2021
1 parent 05a0aec commit 7492543
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -1806,7 +1806,6 @@ static int mod_sysfs_init(struct module *mod)
if (err)
mod_kobject_put(mod);

/* delay uevent until full sysfs population */
out:
return err;
}
Expand Down Expand Up @@ -1843,7 +1842,6 @@ static int mod_sysfs_setup(struct module *mod,
add_sect_attrs(mod, info);
add_notes_attrs(mod, info);

kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD);
return 0;

out_unreg_modinfo_attrs:
Expand Down Expand Up @@ -3499,6 +3497,9 @@ static noinline int do_init_module(struct module *mod)
blocking_notifier_call_chain(&module_notify_list,
MODULE_STATE_LIVE, mod);

/* Delay uevent until module has finished its init routine */
kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD);

/*
* We need to finish all async code before the module init sequence
* is done. This has potential to deadlock. For example, a newly
Expand Down

0 comments on commit 7492543

Please sign in to comment.