Message ID | 301015.1748434697@warthog.procyon.org.uk |
---|---|
State | New |
Headers | show |
Series | KEYS: Invert FINAL_PUT bit | expand |
On Tue, 10 Jun 2025 at 17:23, Paul Moore <paul@paul-moore.com> wrote: > > It doesn't look like this has made its way to Linus. Bah. It "made it" in the sense that sure, it's in my inbox. But particularly during the the early merge window I end up heavily limiting my emails to pull requests. And then it ended up composted at the bottom of my endless pile of emails. I guess I can still take it if people just say "do it". Linus
Linus Torvalds <torvalds@linux-foundation.org> wrote:
> I guess I can still take it if people just say "do it".
Do you want a signed tag and git pull for it?
David
On Wed, 11 Jun 2025 at 11:45, David Howells <dhowells@redhat.com> wrote: > > Do you want a signed tag and git pull for it? Particularly during the merge window that makes sense just to make it trigger my usual "git pull" pattern, but now that I'm more aware of it I can just take the patch directly. Anyway - done just to get this behind us. But for next time, just do it as a signed tag pull request, _particularly_ during the merge window when most other emails get much lower priority. Linus
diff --git a/include/linux/key.h b/include/linux/key.h index ba05de8579ec..81b8f05c6898 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -236,7 +236,7 @@ struct key { #define KEY_FLAG_ROOT_CAN_INVAL 7 /* set if key can be invalidated by root without permission */ #define KEY_FLAG_KEEP 8 /* set if key should not be removed */ #define KEY_FLAG_UID_KEYRING 9 /* set if key is a user or user session keyring */ -#define KEY_FLAG_FINAL_PUT 10 /* set if final put has happened on key */ +#define KEY_FLAG_USER_ALIVE 10 /* set if final put has not happened on key yet */ /* the key type and key description string * - the desc is used to match a key against search criteria diff --git a/security/keys/gc.c b/security/keys/gc.c index f27223ea4578..748e83818a76 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c @@ -218,8 +218,8 @@ static void key_garbage_collector(struct work_struct *work) key = rb_entry(cursor, struct key, serial_node); cursor = rb_next(cursor); - if (test_bit(KEY_FLAG_FINAL_PUT, &key->flags)) { - smp_mb(); /* Clobber key->user after FINAL_PUT seen. */ + if (!test_bit_acquire(KEY_FLAG_USER_ALIVE, &key->flags)) { + /* Clobber key->user after final put seen. */ goto found_unreferenced_key; } diff --git a/security/keys/key.c b/security/keys/key.c index 7198cd2ac3a3..3bbdde778631 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -298,6 +298,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, key->restrict_link = restrict_link; key->last_used_at = ktime_get_real_seconds(); + key->flags |= 1 << KEY_FLAG_USER_ALIVE; if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) key->flags |= 1 << KEY_FLAG_IN_QUOTA; if (flags & KEY_ALLOC_BUILT_IN) @@ -658,8 +659,8 @@ void key_put(struct key *key) key->user->qnbytes -= key->quotalen; spin_unlock_irqrestore(&key->user->lock, flags); } - smp_mb(); /* key->user before FINAL_PUT set. */ - set_bit(KEY_FLAG_FINAL_PUT, &key->flags); + /* Mark key as safe for GC after key->user done. */ + clear_bit_unlock(KEY_FLAG_USER_ALIVE, &key->flags); schedule_work(&key_gc_work); } }