Re: [PATCH] KEYS: Use acquire when reading state in keyring search
Gui-Dong Han <[email protected]> Tue, 2 Jun 2026 17:42:26 +0800
| Newsgroups | org.kernel.vger.keyrings,org.kernel.vger.linux-kernel,org.kernel.vger.linux-security-module |
|---|---|
| Message-ID | <CALbr=LYaca4+=hTsZJORQfrtzyUAGo8c+4ZEgkzgkFWQDWNJBA@mail.gmail.com> |
On Sat, May 30, 2026 at 9:02 AM Jarkko Sakkinen <[email protected]> wrote: > > On Fri, May 29, 2026 at 11:34:06AM +0800, Gui-Dong Han wrote: > > 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 > > > > > Fixes: 363b02dab09b ("KEYS: Fix race between updating and finding a negative key") > > Signed-off-by: Gui-Dong Han <[email protected]> > > --- > > 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