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

Reply via email to