| From 92413ae233b6e4d6dbc685871a90c8a74fc43573 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 27 Nov 2020 10:09:39 +0100 |
| Subject: module: delay kobject uevent until after module init call |
| |
| From: Jessica Yu <jeyu@kernel.org> |
| |
| [ Upstream commit 38dc717e97153e46375ee21797aa54777e5498f3 ] |
| |
| 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> |
| --- |
| kernel/module.c | 5 +++-- |
| 1 file changed, 3 insertions(+), 2 deletions(-) |
| |
| diff --git a/kernel/module.c b/kernel/module.c |
| index b34235082394b..e20499309b2af 100644 |
| --- a/kernel/module.c |
| +++ b/kernel/module.c |
| @@ -1895,7 +1895,6 @@ static int mod_sysfs_init(struct module *mod) |
| if (err) |
| mod_kobject_put(mod); |
| |
| - /* delay uevent until full sysfs population */ |
| out: |
| return err; |
| } |
| @@ -1932,7 +1931,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: |
| @@ -3639,6 +3637,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 |
| -- |
| 2.27.0 |
| |