On 7/13/26 2:13 PM, Aaron Tomlin wrote: > On Mon, Jul 13, 2026 at 10:32:14AM +0200, Arnd Bergmann wrote: >> On Sat, Jul 11, 2026, at 01:13, Aaron Tomlin wrote: >>> On Fri, Jul 10, 2026 at 05:59:59PM +0200, Arnd Bergmann wrote: >>>> On Wed, Jul 8, 2026, at 04:00, Aaron Tomlin wrote: >>>>> Currently, the "module_blacklist=" command-line parameter only applies >>>>> to loadable modules. If a module is built-in, the parameter is silently >>>>> ignored. This patch extends the blacklisting functionality to built-in >>>>> modules by intercepting their initialisation routines during early boot. >>>> >>>> Andrew already asked you to provide more background on what you need >>>> this part for. Do you have a specific driver you need to disable? >>>> >>>> Can't you do the same thing using initcall_blacklist? >>> >>> The primary motivation for this patch is to provide consistent >>> administrative control. >> >> Ok, it sounds like you don't actually need it then. >> >>> Regarding your suggestion to use initcall_blacklist=, while it is certainly >>> a capable mechanism, it is fundamentally considered a debugging facility >>> intended for developers. >> >> I don't see much of a difference here, it's clearly still only a >> debugging tool to me, not a general administrative interface: turning >> off a random built-in driver likely causes undefined behavior later >> if there are any other drivers (built-in or loaded) that depend on it. >> >> Overall I don't think it's worth the added complexity. > > Hi Arnd, > > I appreciate your candour, but I must respectfully disagree with the > assessment that this is merely a debugging tool with no practical > necessity. > > The requirement stems from large-scale infrastructure management and > configuration consistency. System administrators rely on standard > provisioning scripts across diverse hardware. If a distribution arbitrarily > alters a kernel configuration, changing a module from loadable (=m) to > built-in (=y), the administrator's module_blacklist= directive is suddenly > and silently ignored. This creates a severe policy enforcement gap.
Note that a gap will still exist if the administrator previously blacklisted a specific loadable module using the blacklist command in /etc/modprobe.d/ instead of the module_blacklist kernel parameter. > > Regarding the distinction between initcall_blacklist= and > module_blacklist=, the difference lies entirely in ABI stability. > To use initcall_blacklist= requires the administrator to know the exact > internal C function name of the initialisation routine (e.g., > foo_driver_init). This is an internal kernel implementation detail, subject > to change without notice, and entirely undocumented for users. Conversely, > the module name is a stable, well-known, and documented user-facing > identifier. Providing a stable interface for administrative policy is the > very definition of a general administrative tool, rather than a developer > debugging facility. > For example, consider CVE-2021-43267. A system administrator can now use > module_blacklist=tipc which would cover both built-in and loadable module > configurations. > > To address your concern regarding undefined behaviour, disabling a built-in > driver carries the exact same dependency risks as preventing a loadable > module from loading via the traditional blacklist. In both scenarios, > dependent drivers will naturally fail to probe or initialise. System > administrators who apply denylists are already expected to understand the > hardware and software dependencies of the modules they are explicitly > disabling. The dependency risk is somewhat greater with built-in modules. Consider two modules, A and B. Module A exports fun_a() that is used by module B. fun_a() depends on state initialized in A's init function. If both modules are loadable, then B can be inserted only after A has been loaded successfully, that is, A is not blacklisted and its init function completes successfully. If A is built-in and blacklisted, nothing prevents B from calling fun_a() and potentially encountering an undefined state. That said, it seems the same problem can already occur today if A is built-in and fails to initialize, since do_initcall_level() doesn't check the return value from do_one_initcall(). > > I understand your hesitation regarding added complexity. However, with the > fast-path optimisation suggested by Sami (which bypassing the scan entirely > if the parameter is unused), the overhead is essentially zero. I believe > bridging the logical gap between how we treat =m and =y modules is well > worth that minimal footprint. I see the point from a consistency perspective. -- Cheers, Petr

