From: sashiko-bot@kernel.org
To: "Aaron Tomlin" <atomlin@atomlin.com>
Cc: linux-modules@vger.kernel.org
Subject: Re: [PATCH v2] module: Extend module_blacklist parameter to built-in modules
Date: Mon, 22 Jun 2026 14:17:47 +0000 [thread overview]
Message-ID: <20260622141748.0AB5D1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260622140259.2974-1-atomlin@atomlin.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Critical] Accessing the .initcall.modnames array during loadable module initialization reads freed .init memory, causing a Use-After-Free.
- [High] Built-in module blacklisting silently bypasses or fails to compile under CONFIG_LTO_CLANG / CONFIG_CFI_CLANG due to function pointer mismatch.
- [Low] Kernel build fails when CONFIG_MODULES is disabled due to missing module_is_blacklisted() definition.
--
commit 5c29fcaa43d56c5e3cb5426f55d85a536519732f
Author: Aaron Tomlin <atomlin@atomlin.com>
module: Extend module_blacklist parameter to built-in modules
This patch extends the module_blacklist parameter to intercept and prevent
the initialization of built-in modules during system boot. It creates a
.initcall.modnames section mapping initcalls to module names, using 32-bit
relative offsets to preserve KASLR.
Link: https://lore.kernel.org/lkml/20260510061301.41341-1-atomlin@atomlin.com/
> diff --git a/include/linux/init.h b/include/linux/init.h
> index 40331923b9f4a..212f64a07c739 100644
> --- a/include/linux/init.h
> +++ b/include/linux/init.h
[ ... ]
> @@ -270,9 +280,26 @@ extern struct module __this_module;
> __initcall_stub(fn, __iid, id), \
> __initcall_name(initcall, __iid, id), \
> __initcall_section(__sec, __iid))
> +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
> +#define ___define_initcall(fn, id, __sec) \
> + __unique_initcall(fn, id, __sec, __initcall_id(fn)); \
> + asm(".pushsection \".initcall.modnames\", \"a\"\n" \
> + ".balign 4\n" \
> + ".long " #fn " - .\n" \
[Severity: High]
When compiled with CONFIG_LTO_CLANG or CONFIG_CFI_CLANG, the kernel wraps
initcalls in an __initcall_stub function, and stores the stub's address in
the initcall array.
Since ___define_initcall explicitly stores the original function's address
here, will initcall_get_modname() fail to match the runtime CFI/LTO stub
address passed by do_one_initcall()?
Also, could using #fn in inline assembly for a static function renamed by
LTO cause an undefined reference link error?
> + ".long __initcall_modstr_" #fn #id " - .\n" \
> + ".popsection\n" \
> + ".pushsection .init.rodata, \"a\"\n" \
> + "__initcall_modstr_" #fn #id ": .string \"" KBUILD_MODNAME "\"\n" \
> + ".popsection\n");
[ ... ]
> diff --git a/include/linux/module.h b/include/linux/module.h
> index d80c3ea574726..21668ef1430a5 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -754,6 +754,8 @@ void *dereference_module_function_descriptor(struct module *mod, void *ptr);
> int register_module_notifier(struct notifier_block *nb);
> int unregister_module_notifier(struct notifier_block *nb);
>
> +extern bool module_is_blacklisted(const char *module_name);
[Severity: Low]
Does this cause a build failure when CONFIG_MODULES is disabled?
The function module_is_blacklisted() is defined in kernel/module/main.c,
but it is declared here unconditionally and called from do_one_initcall()
in init/main.c. If CONFIG_MODULES is disabled, could the linker fail with
an undefined reference?
> +
> extern void print_modules(void);
[ ... ]
> diff --git a/init/main.c b/init/main.c
> index b84818ad9685f..ce6d769b99e17 100644
> --- a/init/main.c
> +++ b/init/main.c
> @@ -1365,12 +1365,39 @@ static inline void do_trace_initcall_level(const char *level)
> }
> #endif /* !TRACEPOINTS_ENABLED */
>
> +extern struct initcall_modname __start_initcall_modnames[];
> +extern struct initcall_modname __stop_initcall_modnames[];
> +
> +static const char *initcall_get_modname(initcall_t fn)
> +{
> + struct initcall_modname *p;
> +
> + for (p = __start_initcall_modnames; p < __stop_initcall_modnames; p++) {
> + if (initcall_from_entry(&p->initcall_fn) == fn) {
> +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
> + return (const char *)offset_to_ptr(&p->modname_offset);
> +#else
> + return p->modname;
> +#endif
> + }
> + }
> + return NULL;
> +}
> +
> int __init_or_module do_one_initcall(initcall_t fn)
> {
> int count = preempt_count();
> char msgbuf[64];
> + const char *modname;
> int ret;
>
> + modname = initcall_get_modname(fn);
[Severity: Critical]
Is there a use-after-free risk here when loading dynamic modules?
The .initcall.modnames section is placed in INIT_DATA_SECTION, mapping it to
.init.data. Memory in the .init.* sections is freed by free_initmem() after
the system boots.
Since do_one_initcall() is marked __init_or_module, it is also called by
do_init_module() whenever a loadable module is initialized after boot:
do_init_module()
do_one_initcall()
initcall_get_modname()
Does this unconditionally iterate over the __start_initcall_modnames array
residing in the freed .init.data section?
> + if (modname && module_is_blacklisted(modname)) {
> + pr_info("Skipping initcall for blacklisted built-in module %s\n",
> + modname);
> + return 0;
> + }
> +
> if (initcall_blacklisted(fn))
> return -EPERM;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622140259.2974-1-atomlin@atomlin.com?part=1
prev parent reply other threads:[~2026-06-22 14:17 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-22 14:02 [PATCH v2] module: Extend module_blacklist parameter to built-in modules Aaron Tomlin
2026-06-22 14:17 ` sashiko-bot [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260622141748.0AB5D1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=atomlin@atomlin.com \
--cc=linux-modules@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.