On Mon, Jun 22, 2026 at 10:02:59AM -0400, Aaron Tomlin wrote:
> Currently, the module_blacklist= parameter only prevents
> the dynamic loading of external modules. It possesses no mechanism to
> intercept or prevent the initialisation of built-in modules, as their
> associated initcalls are invoked unconditionally during system boot.
>
> This patch extends the blacklisting behaviour to encompass built-in
> modules. It introduces a dedicated ".initcall.modnames" section into
> the linker script, systematically mapping each initcall to its
> originating module name. During the boot sequence, do_one_initcall()
> interrogates this mapping; should the executing initcall belong to a
> blacklisted module, its execution is explicitly bypassed.
Hi Arnd, Luis, Petr, Daniel, Sami,
Sashiko [1] correctly reported issues with this version. Consequently,
in the next iteration, I will implement the following changes:
1. Abandon the raw assembly approach in favour of using standard C
structures (i.e., struct initcall_modname). While this sacrifices
the PREL32 relative offset optimisation for this specific table, it
guarantees architectural safety and ensures native compiler support
for both LTO and CFI.
2. Wrap the module_is_blacklisted declaration in the necessary #ifdef
CONFIG_MODULES guards to prevent undefined reference errors when
loadable module support is disabled.
3. Iterating over .initcall.modnames within the shared
do_one_initcall() path introduces a severe UAF vulnerability when
loadable modules are initialised post-boot. To rectify this, I will
introduce a strict, read-only flag (initmem_freed) to explicitly
bypass the built-in lookup once free_initmem() has reclaimed the
.init sections. Furthermore, to maintain a clean separation of
concerns, the blacklist check for loadable modules will be migrated
directly into the module loader path (do_init_module()).
[1]: https://sashiko.dev/#/patchset/20260622140259.2974-1-atomlin%40atomlin.com
Kind regards,
--
Aaron Tomlin