crypto/asymmetric_keys/asymmetric_type.c | 2 +- security/keys/key.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
From: Daniel Gomez <da.gomez@samsung.com>
The -EEXIST error code is reserved by the module loading infrastructure
to indicate that a module is already loaded. When a module's init
function returns -EEXIST, userspace tools like kmod interpret this as
"module already loaded" and treat the operation as successful, returning
0 to the user even though the module initialization actually failed.
This follows the precedent set by commit 54416fd76770 ("netfilter:
conntrack: helper: Replace -EEXIST by -EBUSY") which fixed the same
issue in nf_conntrack_helper_register().
Affected modules:
* pkcs8_key_parser x509_key_parser asymmetric_keys dns_resolver
* nvme_keyring pkcs7_test_key rxrpc turris_signing_key
Signed-off-by: Daniel Gomez <da.gomez@samsung.com>
---
The error code -EEXIST is reserved by the kernel module loader to
indicate that a module with the same name is already loaded. When a
module's init function returns -EEXIST, kmod interprets this as "module
already loaded" and reports success instead of failure [1].
The kernel module loader will include a safety net that provides -EEXIST
to -EBUSY with a warning [2], and a documentation patch has been sent to
prevent future occurrences [3].
These affected code paths were identified using a static analysis tool
[4] that traces -EEXIST returns to module_init(). The tool was developed
with AI assistance and all findings were manually validated.
Link: https://lore.kernel.org/all/aKEVQhJpRdiZSliu@orbyte.nwl.cc/ [1]
Link: https://lore.kernel.org/all/20251013-module-warn-ret-v1-0-ab65b41af01f@intel.com/ [2]
Link: https://lore.kernel.org/all/20251218-dev-module-init-eexists-modules-docs-v1-0-361569aa782a@samsung.com/ [3]
Link: https://gitlab.com/-/snippets/4913469 [4]
---
crypto/asymmetric_keys/asymmetric_type.c | 2 +-
security/keys/key.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index 348966ea2175..2c6f3a725102 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -634,7 +634,7 @@ int register_asymmetric_key_parser(struct asymmetric_key_parser *parser)
if (strcmp(cursor->name, parser->name) == 0) {
pr_err("Asymmetric key parser '%s' already registered\n",
parser->name);
- ret = -EEXIST;
+ ret = -EBUSY;
goto out;
}
}
diff --git a/security/keys/key.c b/security/keys/key.c
index 3bbdde778631..ed597660f72e 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1219,7 +1219,7 @@ EXPORT_SYMBOL(generic_key_instantiate);
*
* Register a new key type.
*
- * Returns 0 on success or -EEXIST if a type of this name already exists.
+ * Returns 0 on success or -EBUSY if a type of this name already exists.
*/
int register_key_type(struct key_type *ktype)
{
@@ -1228,7 +1228,7 @@ int register_key_type(struct key_type *ktype)
memset(&ktype->lock_class, 0, sizeof(ktype->lock_class));
- ret = -EEXIST;
+ ret = -EBUSY;
down_write(&key_types_sem);
/* disallow key types with the same name */
---
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
change-id: 20251218-dev-module-init-eexists-keyring-5b008d7efb40
Best regards,
--
Daniel Gomez <da.gomez@samsung.com>
Daniel Gomez <da.gomez@kernel.org> wrote:
> From: Daniel Gomez <da.gomez@samsung.com>
>
> The -EEXIST error code is reserved by the module loading infrastructure
> to indicate that a module is already loaded.
EEXIST means a file exists when you're trying to create it. Granted we abuse
that somewhat rather than add ever more error codes, but you cannot reserve it
for indicating that a module exists.
> When a module's init
> function returns -EEXIST, userspace tools like kmod interpret this as
> "module already loaded" and treat the operation as successful, returning
> 0 to the user even though the module initialization actually failed.
>
> This follows the precedent set by commit 54416fd76770 ("netfilter:
> conntrack: helper: Replace -EEXIST by -EBUSY") which fixed the same
> issue in nf_conntrack_helper_register().
>
> Affected modules:
> * pkcs8_key_parser x509_key_parser asymmetric_keys dns_resolver
> * nvme_keyring pkcs7_test_key rxrpc turris_signing_key
>
> Signed-off-by: Daniel Gomez <da.gomez@samsung.com>
Please don't. Userspace can always check /proc/modules (assuming procfs is
enabled, I suppose).
David
+Greg, to consolidate from the othe thread.
On Mon, Jan 05, 2026 at 09:57:15AM +0000, David Howells wrote:
>Daniel Gomez <da.gomez@kernel.org> wrote:
>
>> From: Daniel Gomez <da.gomez@samsung.com>
>>
>> The -EEXIST error code is reserved by the module loading infrastructure
>> to indicate that a module is already loaded.
>
>EEXIST means a file exists when you're trying to create it. Granted we abuse
>that somewhat rather than add ever more error codes, but you cannot reserve it
>for indicating that a module exists.
EEXIST from [f]init_module() means "module is already loaded" and it
can't mean something else for this syscall. Other return codes are
explained in the man page, but aren't that special from the userspace
pov.
This doesn't mean we need to replace all the EBUSY throughout the call
chain with EEXIST, but the return from the syscall needs to remain
consistent if that was the case for it failing. Ideally that mapping
would come from the module init (and not from other functions it calls)
because that is the place that has that knowledge.
If a generic EBUSY->EEXIST mapping is desired, as it seems to be the
case from
https://lore.kernel.org/all/2025122212-fiction-setback-ede5@gregkh/,
then do_init_module() can do it, but in practice that means reserving 2
error codes rather than 1.
>
>> When a module's init
>> function returns -EEXIST, userspace tools like kmod interpret this as
>> "module already loaded" and treat the operation as successful, returning
>> 0 to the user even though the module initialization actually failed.
>>
>> This follows the precedent set by commit 54416fd76770 ("netfilter:
>> conntrack: helper: Replace -EEXIST by -EBUSY") which fixed the same
>> issue in nf_conntrack_helper_register().
>>
>> Affected modules:
>> * pkcs8_key_parser x509_key_parser asymmetric_keys dns_resolver
>> * nvme_keyring pkcs7_test_key rxrpc turris_signing_key
>>
>> Signed-off-by: Daniel Gomez <da.gomez@samsung.com>
>
>Please don't. Userspace can always check /proc/modules (assuming procfs is
>enabled, I suppose).
EEXIST is already there with that meaning. Checking procfs (or sysfs as
kmod currently does) is racy and doesn't look like a good API - why
would userspace have to check if the module is loaded when the syscall
that loads the module failed? EEXIST is special exactly to resolve races
with 2 threads trying to load the same module.
Lucas De Marchi
>
>David
>
On Sat, Dec 20, 2025 at 04:50:31AM +0100, Daniel Gomez wrote:
> The -EEXIST error code is reserved by the module loading infrastructure
> to indicate that a module is already loaded. When a module's init
> function returns -EEXIST, userspace tools like kmod interpret this as
> "module already loaded" and treat the operation as successful, returning
> 0 to the user even though the module initialization actually failed.
>
> This follows the precedent set by commit 54416fd76770 ("netfilter:
> conntrack: helper: Replace -EEXIST by -EBUSY") which fixed the same
> issue in nf_conntrack_helper_register().
>
> Affected modules:
> * pkcs8_key_parser x509_key_parser asymmetric_keys dns_resolver
> * nvme_keyring pkcs7_test_key rxrpc turris_signing_key
For the record, GregKH summarily rejected this approach:
https://lore.kernel.org/r/2025122212-fiction-setback-ede5@gregkh/
Thanks,
Lukas
© 2016 - 2026 Red Hat, Inc.