[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <14a57def-b2da-491b-ad97-19b784d0d594@kernel.org>
Date: Mon, 3 Nov 2025 10:05:26 +0100
From: Hans Verkuil <hverkuil+cisco@...nel.org>
To: Daniel Gomez <da.gomez@...nel.org>, Kees Cook <kees@...nel.org>,
 Luis Chamberlain <mcgrof@...nel.org>
Cc: Rusty Russell <rusty@...tcorp.com.au>, Petr Pavlu <petr.pavlu@...e.com>,
 Sami Tolvanen <samitolvanen@...gle.com>, linux-modules@...r.kernel.org,
 Malcolm Priestley <tvboxspy@...il.com>,
 Mauro Carvalho Chehab <mchehab@...nel.org>,
 Hans Verkuil <hverkuil@...nel.org>,
 Uwe Kleine-König <u.kleine-koenig@...gutronix.de>,
 linux-kernel@...r.kernel.org, linux-media@...r.kernel.org,
 linux-hardening@...r.kernel.org
Subject: Re: [PATCH v2 3/3] module: Add compile-time check for embedded NUL
 characters
On 03/11/2025 09:58, Daniel Gomez wrote:
> On 03/11/2025 09.54, Hans Verkuil wrote:
>> On 10/10/2025 05:06, Kees Cook wrote:
>>> Long ago, the kernel module license checks were bypassed by embedding a
>>> NUL character in the MODULE_LICENSE() string[1]. By using a string like
>>> "GPL\0proprietary text", the kernel would only read "GPL" due to C string
>>> termination at the NUL byte, allowing proprietary modules to avoid kernel
>>> tainting and access GPL-only symbols.
>>>
>>> The MODULE_INFO() macro stores these strings in the .modinfo ELF
>>> section, and get_next_modinfo() uses strcmp()-family functions
>>> which stop at the first NUL. This split the embedded string into two
>>> separate .modinfo entries, with only the first part being processed by
>>> license_is_gpl_compatible().
>>>
>>> Add a compile-time check using static_assert that compares the full
>>> string length (sizeof - 1) against __builtin_strlen(), which stops at
>>> the first NUL. If they differ, compilation fails with a clear error
>>> message.
>>>
>>> While this check can still be circumvented by modifying the ELF binary
>>> post-compilation, it prevents accidental embedded NULs and forces
>>> intentional abuse to require deliberate binary manipulation rather than
>>> simple source-level tricks.
>>>
>>> Build tested with test modules containing both valid and invalid license
>>> strings. The check correctly rejects:
>>>
>>>     MODULE_LICENSE("GPL\0proprietary")
>>>
>>> while accepting normal declarations:
>>>
>>>     MODULE_LICENSE("GPL")
>>
>> Who will take this series? I can take the first two media patches and
>> someone else can take this last patch, or I can take all, or someone
>> else can take all patches. The media patches already have my 'Reviewed-by'.
>>
>> Any preferences?
> 
> I will take patch 3 in modules' tree.
OK, then I'll take patches 1 and 2 in the media tree.
Regards,
	Hans
> 
> 
>>
>> Regards,
>>
>> 	Hans
>>
>>>
>>> Link: https://lwn.net/Articles/82305/ [1]
>>> Suggested-by: Rusty Russell <rusty@...tcorp.com.au>
>>> Signed-off-by: Kees Cook <kees@...nel.org>
> 
> Reviewed-by: Daniel Gomez <da.gomez@...sung.com>
Powered by blists - more mailing lists