From: Jarkko Sakkinen <jarkko@kernel.org>
To: Yuansheng Yang <0xbeac@gmail.com>
Cc: David Howells <dhowells@redhat.com>,
Paul Moore <paul@paul-moore.com>,
James Morris <jmorris@namei.org>,
"Serge E. Hallyn" <serge@hallyn.com>,
keyrings@vger.kernel.org, linux-security-module@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH v5] KEYS: Protect pkey method checks against type removal
Date: Sun, 8 Nov 2026 17:45:36 +0200 [thread overview]
Message-ID: <avCZIMCsZ4um18e-@kernel.org> (raw)
In-Reply-To: <20261108131417.77287-1-0xbeac@gmail.com>
On Sun, Nov 08, 2026 at 09:14:17PM +0800, Yuansheng Yang wrote:
> keyctl_pkey_query(), keyctl_pkey_e_d_s() and keyctl_pkey_verify() check
> that key->type has the ->asym_*() method they need and call it later,
> without holding key->sem. A reference keeps the key alive, but does not
> pin the module that provides its type.
>
> When that module is unloaded, unregister_key_type() waits for the key GC
> to process every remaining key of the type. For each such key, the GC
> takes key->sem for writing, switches key->type to key_type_dead, whose
> ->asym_*() methods are NULL, and destroys the payload. If this happens
> between the check and the call, the keyctl calls a NULL method:
>
> KEYCTL_PKEY_SIGN task Module unload and key GC
> ------------------------ ------------------------
> keyctl_pkey_e_d_s()
> if (!key->type->asym_eds_op) unregister_key_type()
> GC: down_write(&key->sem)
> GC: retype to key_type_dead
> GC: up_write(&key->sem)
> free_module()
> in = memdup_user(...)
> key->type->asym_eds_op(...) -> NULL call
>
> If it happens while the method is running, the method is left running in
> freed module text. In-tree, turris-signing-key provides ->asym_query()
> and ->asym_eds_op() and can be built as a module.
>
> Take key->sem for reading around each ->asym_*() call, and check the
> method again under it, right before the call. While key->sem is held,
> the GC cannot switch the key to key_type_dead, so unregister_key_type(),
> and with it the module unload, cannot complete: the type, its module and
> the payload stay in place until the method returns. If the type is
> already gone when key->sem is taken, the check finds key_type_dead and
> the keyctl fails with -EOPNOTSUPP, as it does for any key type without
> the method.
>
> Otherwise, behaviour is unchanged:
>
> - The existing checks in keyctl_pkey_params_get(), keyctl_pkey_e_d_s()
> and keyctl_pkey_verify() are kept, so key types without the method
> still fail at the same point with the same error. No call relies on
> them any more.
>
> - memdup_user() and copy_to_user() stay outside key->sem, as in
> keyctl_read_key(), so no page fault is taken with key->sem held.
>
> - key->sem is only taken for reading, so pkey operations and KEYCTL_READ
> on the same key still run concurrently. Writers such as KEYCTL_UPDATE,
> KEYCTL_REVOKE and KEYCTL_SETPERM now wait for a pkey operation in
> progress, as they already wait for ->read(). The in-tree ->asym_*()
> methods do not take key->sem themselves.
>
> Nothing else in the kernel calls these three methods, so the four call
> sites below are the full coverage:
>
> - keyctl_pkey_query(): ->asym_query() for KEYCTL_PKEY_QUERY
> - keyctl_pkey_params_get_2(): ->asym_query() to check the buffer sizes
> for KEYCTL_PKEY_ENCRYPT, _DECRYPT, _SIGN and _VERIFY
> - keyctl_pkey_e_d_s(): ->asym_eds_op() for KEYCTL_PKEY_ENCRYPT,
> _DECRYPT and _SIGN
> - keyctl_pkey_verify(): ->asym_verify_signature() for
> KEYCTL_PKEY_VERIFY
>
> This problem was recently fixed for keyctl_read_key() by 925c84e3cc21
> ("keys: Protect the read method check against type removal") and for
> key_update() by aef3a8a4f988 ("KEYS: Protect the update method check
> against type removal").
>
> LLM assistants, OpenAI Codex (gpt-6.1-sol) and Anthropic Claude
> (claude-opus-5-5), found this while looking for other cases of the
> KEYCTL_READ problem, and drafted this patch and this description.
This paragrah is no longer required and can be removed. I'll make only
sure that you know what you're doing. LLM is equal to a text editor as
far as I'm concerned, which also LLM is neither excuse for anything.
I think this is fine but there was a Sashiko issue left that
still needs to be fixed.
>
> Fixes: 00d60fd3b932 ("KEYS: Provide keyctls to drive the new key type ops for asymmetric keys [ver #2]")
> Cc: stable@vger.kernel.org
> Signed-off-by: Yuansheng Yang <0xbeac@gmail.com>
Br, Jarkko
prev parent reply other threads:[~2026-11-08 15:45 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 3:29 [PATCH] " BeaCox
2026-11-03 15:17 ` Jarkko Sakkinen
2026-11-04 2:14 ` [PATCH v2] " BeaCox
2026-11-04 14:49 ` Jarkko Sakkinen
2026-11-04 23:59 ` Jarkko Sakkinen
2026-11-05 2:24 ` Yuansheng Yang
2026-11-05 3:28 ` Jarkko Sakkinen
2026-11-05 4:38 ` [PATCH v3] " Yuansheng Yang
2026-11-05 16:55 ` Jarkko Sakkinen
2026-11-05 19:36 ` [PATCH v4] " Yuansheng Yang
2026-11-06 14:08 ` Jarkko Sakkinen
2026-11-08 12:59 ` Yuansheng Yang
2026-11-08 13:14 ` [PATCH v5] " Yuansheng Yang
2026-11-08 15:45 ` Jarkko Sakkinen [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=avCZIMCsZ4um18e-@kernel.org \
--to=jarkko@kernel.org \
--cc=0xbeac@gmail.com \
--cc=dhowells@redhat.com \
--cc=jmorris@namei.org \
--cc=keyrings@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=paul@paul-moore.com \
--cc=serge@hallyn.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®