* [PATCH] kernel: fix error handling in lookup_or_create_module_kobject()
@ 2025-05-06 11:17 Dmitry Antipov
2025-05-06 14:49 ` Petr Pavlu
0 siblings, 1 reply; 5+ messages in thread
From: Dmitry Antipov @ 2025-05-06 11:17 UTC (permalink / raw)
To: Luis Chamberlain
Cc: Petr Pavlu, Sami Tolvanen, Daniel Gomez, Shyam Saini,
linux-modules, Dmitry Antipov, syzbot+7fb8a372e1f6add936dd
In 'lookup_or_create_module_kobject()', an internal kobject is created
using 'module_ktype'. So plain 'kobject_put()' causes an attempt to use
an uninitialied completion pointer in 'module_kobject_release()' and
'mod_kobject_put()' should be used instead. But if the driver (e.g. USB
gadget as in this particular case reported by syzkaller) is configured
as compiled-in, THIS_MODULE is NULL and there is no relevant module
object to call the latter against. So introduce an internal wrapper
'__module_kobject_put()' which is expected 'struct module_kobject' and
so fix error handling in 'lookup_or_create_module_kobject()'.
Reported-by: syzbot+7fb8a372e1f6add936dd@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=7fb8a372e1f6add936dd
Fixes: 1c7777feb0e2 ("kernel: refactor lookup_or_create_module_kobject()")
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
include/linux/module.h | 3 +++
kernel/module/sysfs.c | 15 ++++++++++-----
kernel/params.c | 3 ++-
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/include/linux/module.h b/include/linux/module.h
index b3329110d668..2b4ab389c1bc 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -891,6 +891,9 @@ static inline void module_for_each_mod(int(*func)(struct module *mod, void *data
#ifdef CONFIG_SYSFS
extern struct kset *module_kset;
extern const struct kobj_type module_ktype;
+void __module_kobject_put(struct module_kobject *mkobj);
+#else /* not CONFIG_SYSFS */
+static inline void __module_kobject_put(struct module_kobject *mkobj) { }
#endif /* CONFIG_SYSFS */
#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c
index b401ff4b02d2..7519920f4f55 100644
--- a/kernel/module/sysfs.c
+++ b/kernel/module/sysfs.c
@@ -323,11 +323,7 @@ static int module_add_modinfo_attrs(struct module *mod)
static void mod_kobject_put(struct module *mod)
{
- DECLARE_COMPLETION_ONSTACK(c);
-
- mod->mkobj.kobj_completion = &c;
- kobject_put(&mod->mkobj.kobj);
- wait_for_completion(&c);
+ __module_kobject_put(&mod->mkobj);
}
static int mod_sysfs_init(struct module *mod)
@@ -362,6 +358,15 @@ static int mod_sysfs_init(struct module *mod)
return err;
}
+void __module_kobject_put(struct module_kobject *mkobj)
+{
+ DECLARE_COMPLETION_ONSTACK(c);
+
+ mkobj->kobj_completion = &c;
+ kobject_put(&mkobj->kobj);
+ wait_for_completion(&c);
+}
+
int mod_sysfs_setup(struct module *mod,
const struct load_info *info,
struct kernel_param *kparam,
diff --git a/kernel/params.c b/kernel/params.c
index e668fc90b83e..2cf1f17840e0 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -780,7 +780,8 @@ struct module_kobject __modinit * lookup_or_create_module_kobject(const char *na
if (IS_ENABLED(CONFIG_MODULES) && !err)
err = sysfs_create_file(&mk->kobj, &module_uevent.attr);
if (err) {
- kobject_put(&mk->kobj);
+ /* Not 'mod_kobject_put()' because THIS_MODULE may be NULL. */
+ __module_kobject_put(mk);
pr_crit("Adding module '%s' to sysfs failed (%d), the system may be unstable.\n",
name, err);
return NULL;
--
2.49.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] kernel: fix error handling in lookup_or_create_module_kobject()
2025-05-06 11:17 [PATCH] kernel: fix error handling in lookup_or_create_module_kobject() Dmitry Antipov
@ 2025-05-06 14:49 ` Petr Pavlu
2025-05-07 6:05 ` Dmitry Antipov
2025-05-07 6:50 ` [PATCH] module: ensure that kobject_put() is safe for module type kobjects Dmitry Antipov
0 siblings, 2 replies; 5+ messages in thread
From: Petr Pavlu @ 2025-05-06 14:49 UTC (permalink / raw)
To: Dmitry Antipov
Cc: Luis Chamberlain, Sami Tolvanen, Daniel Gomez, Shyam Saini,
linux-modules, syzbot+7fb8a372e1f6add936dd
On 5/6/25 13:17, Dmitry Antipov wrote:
> In 'lookup_or_create_module_kobject()', an internal kobject is created
> using 'module_ktype'. So plain 'kobject_put()' causes an attempt to use
> an uninitialied completion pointer in 'module_kobject_release()' and
> 'mod_kobject_put()' should be used instead. But if the driver (e.g. USB
> gadget as in this particular case reported by syzkaller) is configured
> as compiled-in, THIS_MODULE is NULL and there is no relevant module
> object to call the latter against. So introduce an internal wrapper
> '__module_kobject_put()' which is expected 'struct module_kobject' and
> so fix error handling in 'lookup_or_create_module_kobject()'.
>
> Reported-by: syzbot+7fb8a372e1f6add936dd@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=7fb8a372e1f6add936dd
> Fixes: 1c7777feb0e2 ("kernel: refactor lookup_or_create_module_kobject()")
I think this specific commit is harmless, rather the underlying problem
was introduced already in 942e443127e9 ("module: Fix mod->mkobj.kobj
potentially freed too early"). Commit f95bbfe18512 ("drivers: base:
handle module_kobject creation") now allowed the problematic code to be
reached by more paths and enabled syzkaller to find it.
> [...]
> diff --git a/include/linux/module.h b/include/linux/module.h
> index b3329110d668..2b4ab389c1bc 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -891,6 +891,9 @@ static inline void module_for_each_mod(int(*func)(struct module *mod, void *data
> #ifdef CONFIG_SYSFS
> extern struct kset *module_kset;
> extern const struct kobj_type module_ktype;
> +void __module_kobject_put(struct module_kobject *mkobj);
> +#else /* not CONFIG_SYSFS */
> +static inline void __module_kobject_put(struct module_kobject *mkobj) { }
> #endif /* CONFIG_SYSFS */
>
> #define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
> diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c
> index b401ff4b02d2..7519920f4f55 100644
> --- a/kernel/module/sysfs.c
> +++ b/kernel/module/sysfs.c
> @@ -323,11 +323,7 @@ static int module_add_modinfo_attrs(struct module *mod)
>
> static void mod_kobject_put(struct module *mod)
> {
> - DECLARE_COMPLETION_ONSTACK(c);
> -
> - mod->mkobj.kobj_completion = &c;
> - kobject_put(&mod->mkobj.kobj);
> - wait_for_completion(&c);
> + __module_kobject_put(&mod->mkobj);
> }
>
> static int mod_sysfs_init(struct module *mod)
> @@ -362,6 +358,15 @@ static int mod_sysfs_init(struct module *mod)
> return err;
> }
>
> +void __module_kobject_put(struct module_kobject *mkobj)
> +{
> + DECLARE_COMPLETION_ONSTACK(c);
> +
> + mkobj->kobj_completion = &c;
> + kobject_put(&mkobj->kobj);
> + wait_for_completion(&c);
> +}
> +
> int mod_sysfs_setup(struct module *mod,
> const struct load_info *info,
> struct kernel_param *kparam,
> diff --git a/kernel/params.c b/kernel/params.c
> index e668fc90b83e..2cf1f17840e0 100644
> --- a/kernel/params.c
> +++ b/kernel/params.c
> @@ -780,7 +780,8 @@ struct module_kobject __modinit * lookup_or_create_module_kobject(const char *na
> if (IS_ENABLED(CONFIG_MODULES) && !err)
> err = sysfs_create_file(&mk->kobj, &module_uevent.attr);
> if (err) {
> - kobject_put(&mk->kobj);
> + /* Not 'mod_kobject_put()' because THIS_MODULE may be NULL. */
> + __module_kobject_put(mk);
> pr_crit("Adding module '%s' to sysfs failed (%d), the system may be unstable.\n",
> name, err);
> return NULL;
This looks as a valid fix, but I wonder if it wouldn't be simpler to
have module_kobj_release() check if mk->kobj_completion is NULL.
--
Thanks,
Petr
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] kernel: fix error handling in lookup_or_create_module_kobject()
2025-05-06 14:49 ` Petr Pavlu
@ 2025-05-07 6:05 ` Dmitry Antipov
2025-05-07 6:50 ` [PATCH] module: ensure that kobject_put() is safe for module type kobjects Dmitry Antipov
1 sibling, 0 replies; 5+ messages in thread
From: Dmitry Antipov @ 2025-05-07 6:05 UTC (permalink / raw)
To: Petr Pavlu
Cc: Luis Chamberlain, Sami Tolvanen, Daniel Gomez, Shyam Saini,
linux-modules, syzbot+7fb8a372e1f6add936dd
On 5/6/25 5:49 PM, Petr Pavlu wrote:
> This looks as a valid fix, but I wonder if it wouldn't be simpler to
> have module_kobj_release() check if mk->kobj_completion is NULL.
Indeed. Just submitted to syzbot and will send v2 if passed.
Dmitry
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] module: ensure that kobject_put() is safe for module type kobjects
2025-05-06 14:49 ` Petr Pavlu
2025-05-07 6:05 ` Dmitry Antipov
@ 2025-05-07 6:50 ` Dmitry Antipov
2025-05-07 18:20 ` Petr Pavlu
1 sibling, 1 reply; 5+ messages in thread
From: Dmitry Antipov @ 2025-05-07 6:50 UTC (permalink / raw)
To: Petr Pavlu
Cc: Luis Chamberlain, Sami Tolvanen, Daniel Gomez, Shyam Saini,
linux-modules, Dmitry Antipov, syzbot+7fb8a372e1f6add936dd
In 'lookup_or_create_module_kobject()', an internal kobject is created
using 'module_ktype'. So call to 'kobject_put()' on error handling
path causes an attempt to use an uninitialized completion pointer in
'module_kobject_release()'. In this scenario, we just want to release
kobject without an extra synchronization required for a regular module
unloading process, so adding an extra check whether 'complete()' is
actually required makes 'kobject_put()' safe.
Reported-by: syzbot+7fb8a372e1f6add936dd@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=7fb8a372e1f6add936dd
Fixes: 942e443127e9 ("module: Fix mod->mkobj.kobj potentially freed too early")
Suggested-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
kernel/params.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/kernel/params.c b/kernel/params.c
index e668fc90b83e..b92d64161b75 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -943,7 +943,9 @@ struct kset *module_kset;
static void module_kobj_release(struct kobject *kobj)
{
struct module_kobject *mk = to_module_kobject(kobj);
- complete(mk->kobj_completion);
+
+ if (mk->kobj_completion)
+ complete(mk->kobj_completion);
}
const struct kobj_type module_ktype = {
--
2.49.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] module: ensure that kobject_put() is safe for module type kobjects
2025-05-07 6:50 ` [PATCH] module: ensure that kobject_put() is safe for module type kobjects Dmitry Antipov
@ 2025-05-07 18:20 ` Petr Pavlu
0 siblings, 0 replies; 5+ messages in thread
From: Petr Pavlu @ 2025-05-07 18:20 UTC (permalink / raw)
To: Dmitry Antipov
Cc: Luis Chamberlain, Sami Tolvanen, Daniel Gomez, Shyam Saini,
linux-modules, syzbot+7fb8a372e1f6add936dd
On 5/7/25 08:50, Dmitry Antipov wrote:
> In 'lookup_or_create_module_kobject()', an internal kobject is created
> using 'module_ktype'. So call to 'kobject_put()' on error handling
> path causes an attempt to use an uninitialized completion pointer in
> 'module_kobject_release()'. In this scenario, we just want to release
> kobject without an extra synchronization required for a regular module
> unloading process, so adding an extra check whether 'complete()' is
> actually required makes 'kobject_put()' safe.
>
> Reported-by: syzbot+7fb8a372e1f6add936dd@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=7fb8a372e1f6add936dd
> Fixes: 942e443127e9 ("module: Fix mod->mkobj.kobj potentially freed too early")
> Suggested-by: Petr Pavlu <petr.pavlu@suse.com>
> Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Added on modules-fixes.
I plan to send the fix to Linus on Friday. While the underlying problem
was already there, commit f95bbfe18512 ("drivers: base: handle
module_kobject creation"), merged in v6.15-rc5, made it more exposed and
I think it's better to have it fixed in this cycle. The patch itself is
also safe.
--
Thanks,
Petr
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-05-07 18:20 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-06 11:17 [PATCH] kernel: fix error handling in lookup_or_create_module_kobject() Dmitry Antipov
2025-05-06 14:49 ` Petr Pavlu
2025-05-07 6:05 ` Dmitry Antipov
2025-05-07 6:50 ` [PATCH] module: ensure that kobject_put() is safe for module type kobjects Dmitry Antipov
2025-05-07 18:20 ` Petr Pavlu
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.