Thread (4 messages) 4 messages, 2 authors, 2026-06-08

Re: [PATCH] KEYS: Use acquire when reading state in keyring search

From: Gui-Dong Han <hidden>
Date: 2026-06-02 09:42:35
Also in: keyrings, lkml

On Sat, May 30, 2026 at 9:02 AM Jarkko Sakkinen [off-list ref] wrote:
On Fri, May 29, 2026 at 11:34:06AM +0800, Gui-Dong Han wrote:
quoted
The negative-key race fix added release/acquire ordering for key use.

Publish payload before state; read state before payload.

keyring_search_iterator() still uses READ_ONCE() before match callbacks.
An asymmetric match callback calls asymmetric_key_ids(), which reads
key->payload.data[asym_key_ids].

Use key_read_state() there to complete that ordering.
OK, so... I'm having a bit trouble understanding the exact concurrency
scenario you're trying to describe despite I think I get the fix itself
i.e. it is not pairing with mark_key_instantiated?
Yes, it is intended to pair with mark_key_instantiated().
I'm a bit puzzled too why this was not done already in the original
commit despite introducing all the primitives.
The original commit added the right primitives, but this site was easy to
miss because the payload access is hidden behind ctx->match_data.cmp().
For example, the asymmetric match callbacks call asymmetric_key_ids(),
which reads key->payload.data[asym_key_ids].

I also checked the two pre-existing issues reported by Sashiko [1].
The uninitialized-read case does not look possible from the code, but the
cached-error issue is real and was dynamically reproduced.  I can send a
separate patch for that if useful.

Thanks.

[1] https://sashiko.dev/#/patchset/20260529033406.20673-1-hanguidong02%40gmail.com
quoted
Fixes: 363b02dab09b ("KEYS: Fix race between updating and finding a negative key")
Signed-off-by: Gui-Dong Han <redacted>
---
Found by auditing READ_ONCE() used for synchronization.
A similar fix can be found in 8df672bfe3ec.
---
 security/keys/keyring.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index b39038f7dd31..243fb1636f10 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -576,7 +576,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
      struct keyring_search_context *ctx = iterator_data;
      const struct key *key = keyring_ptr_to_key(object);
      unsigned long kflags = READ_ONCE(key->flags);
-     short state = READ_ONCE(key->state);
+     short state = key_read_state(key);

      kenter("{%d}", key->serial);

--
2.34.1
BR, Jarkko
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help