All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jarkko Sakkinen" <jarkko@kernel.org>,
	"David Howells" <dhowells@redhat.com>
Cc: "Eric Biggers" <ebiggers@kernel.org>,
	"Mimi Zohar" <zohar@linux.ibm.com>,
	keyrings@vger.kernel.org,
	"Roberto Sassu" <roberto.sassu@huawei.com>,
	"Dmitry Kasatkin" <dmitry.kasatkin@gmail.com>,
	"Eric Snowberg" <eric.snowberg@oracle.com>,
	"Paul Moore" <paul@paul-moore.com>,
	"James Morris" <jmorris@namei.org>,
	"Serge E. Hallyn" <serge@hallyn.com>,
	"open list:SECURITY SUBSYSTEM"
	<linux-security-module@vger.kernel.org>
Subject: Re: [RFC PATCH v2 01/11] KEYS: Add key_gc_flush() for draining RCU callbacks
Date: Wed, 04 Nov 2026 03:03:01 +0000	[thread overview]
Message-ID: <sashiko-outbox-196565@kernel.org> (raw)
In-Reply-To: <20261103030226.2685251-2-jarkko@kernel.org>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] KEYS: premature return in key_gc_flush() when key_gc_work queues RCU
--

commit e02fb1ccece5874817985c8b64ba41bf90bc5796
Author: Jarkko Sakkinen <jarkko@kernel.org>

KEYS: Add key_gc_flush() for draining RCU callbacks

This commit introduces key_gc_flush() to drain RCU callbacks and flush
key_gc_work until no further garbage collection passes remain queued. This
provides callers clearing an internal key cache before module unload with a
synchronous barrier for key destruction.

> diff --git a/security/keys/gc.c b/security/keys/gc.c
> index eda445f815d47..3cfbf00085b3d 100644
> --- a/security/keys/gc.c
> +++ b/security/keys/gc.c
> @@ -21,6 +21,20 @@ unsigned key_gc_delay = 5 * 60;
>  static void key_garbage_collector(struct work_struct *work);
>  DECLARE_WORK(key_gc_work, key_garbage_collector);
>  
> +/**
> + * key_gc_flush - Wait for pending key unlinks and garbage collection.
> + *
> + * Drain RCU callbacks from keyring edits and wait for the key garbage
> + * collector work item to finish reaping unreferenced keys.
> + */
> +void key_gc_flush(void)
> +{
> +	do {
> +		rcu_barrier();
> +	} while (flush_work(&key_gc_work));
> +}
> +EXPORT_SYMBOL_GPL(key_gc_flush);

[Severity: Medium]
Can key_gc_flush() return prematurely before keys invalidated by
key_invalidate() or key_remove_domain() are unlinked and reaped?

Unlike keyring_clear(), which queues assoc_array_rcu_cleanup() via call_rcu()
synchronously before returning, key_invalidate() schedules key_gc_work to
reap links first:

security/keys/key.c:key_invalidate() {
	if (!test_bit(KEY_FLAG_INVALIDATED, &key->flags)) {
		down_write_nested(&key->sem, 1);
		if (!test_and_set_bit(KEY_FLAG_INVALIDATED, &key->flags)) {
			notify_key(key, NOTIFY_KEY_INVALIDATED, 0);
			key_schedule_gc_links();
		}
		up_write(&key->sem);
	}
}

When key_garbage_collector() runs the link-reaping pass at found_keyring, it
calls keyring_gc() -> assoc_array_gc() -> assoc_array_apply_edit(), which
queues assoc_array_rcu_cleanup() via call_rcu() without setting
KEY_GC_REAP_AGAIN:

security/keys/gc.c:key_garbage_collector() {
	/* We found a keyring and we need to check the payload for links to
	 * dead or expired keys.  We don't flag another reap immediately as we
	 * have to wait for the old payload to be destroyed by RCU before we
	 * can reap the keys to which it refers.
	 */
found_keyring:
	spin_unlock(&key_serial_lock);
	keyring_gc(key, limit);
	goto maybe_resched;
}

Because key_gc_flush() calls rcu_barrier() before flush_work(&key_gc_work),
if key_invalidate() is followed by key_gc_flush(), the RCU callback is not
queued yet when the first rcu_barrier() starts. If key_gc_work runs
keyring_gc(), queues edit->rcu via call_rcu() after rcu_barrier() has already
passed that CPU (or returned), and finishes before flush_work(&key_gc_work)
is reached, flush_work(&key_gc_work) sees the work item is already idle and
returns false.

At that point the loop exits while assoc_array_rcu_cleanup() is still pending
in RCU, key_put() has not been called on the unlinked key, and
key_gc_unused_keys() has not reaped it.

Should flush_work(&key_gc_work) be called before rcu_barrier() in the loop
so that any pending link-reaping pass queues its RCU callbacks before
rcu_barrier() waits for them?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261103030226.2685251-1-jarkko@kernel.org?part=1

  reply	other threads:[~2026-11-04  3:03 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-03  3:02 [RFC PATCH v2 00/11] KEYS: Sanitize the garbage collector Jarkko Sakkinen
2026-11-03  3:02 ` [RFC PATCH v2 01/11] KEYS: Add key_gc_flush() for draining RCU callbacks Jarkko Sakkinen
2026-11-04  3:03   ` sashiko-bot [this message]
2026-11-03  3:02 ` [RFC PATCH v2 02/11] nvme-keyring: Add a missing key_put() call to nvme_tls_key_lookup() Jarkko Sakkinen
2026-11-03  5:33   ` Christoph Hellwig
2026-11-03 12:29     ` Jarkko Sakkinen
2026-11-04  9:04       ` Christoph Hellwig
2026-11-04 14:43         ` Jarkko Sakkinen
2026-11-04 15:53           ` Keith Busch
2026-11-04  3:03   ` sashiko-bot
2026-11-04  7:45   ` Hannes Reinecke
2026-11-04 14:43     ` Jarkko Sakkinen
2026-11-04 20:37   ` (subset) " Keith Busch
2026-11-04 23:44     ` Jarkko Sakkinen
2026-11-03  3:02 ` [RFC PATCH v2 03/11] dns_resolver: Clear .dns_resolver cache when the last client unloads Jarkko Sakkinen
2026-11-04  3:03   ` sashiko-bot
2026-11-03  3:02 ` [RFC PATCH v2 04/11] NFSv4: Clear idmap keyring " Jarkko Sakkinen
2026-11-04  3:03   ` sashiko-bot
2026-11-03  3:02 ` [RFC PATCH v2 05/11] smb: client: Clear idmap/SPNEGO caches when the last session is unloaded Jarkko Sakkinen
2026-11-04  3:03   ` sashiko-bot
2026-11-03  3:02 ` [RFC PATCH v2 06/11] s390/cert_store: Track subsystem keys instead of re-registering key_type Jarkko Sakkinen
2026-11-03 12:06   ` Jarkko Sakkinen
2026-11-04  3:03   ` sashiko-bot
2026-11-03  3:02 ` [RFC PATCH v2 07/11] KEYS: trusted: TEE: Disable sysfs bind attributes Jarkko Sakkinen
2026-11-04  3:03   ` sashiko-bot
2026-11-03  3:02 ` [RFC PATCH v2 08/11] KEYS: trusted: TEE: Synchronize session lifetime Jarkko Sakkinen
2026-11-04  3:03   ` sashiko-bot
2026-11-03  3:02 ` [RFC PATCH v2 09/11] KEYS: Pin the backing kernel module for a key type Jarkko Sakkinen
2026-11-04  3:03   ` sashiko-bot
2026-11-03  3:02 ` [RFC PATCH v2 10/11] KEYS: Remove key_type_dead Jarkko Sakkinen
2026-11-04  3:03   ` sashiko-bot
2026-11-03  3:02 ` [RFC PATCH v2 11/11] KEYS: key_garbage_collector(): process in chunks Jarkko Sakkinen
2026-11-04  3:03   ` sashiko-bot
2026-11-03  3:10 ` [RFC PATCH v2 00/11] KEYS: Sanitize the garbage collector Jarkko Sakkinen
2026-11-03 12:32   ` Jarkko Sakkinen
2026-11-03 10:03 ` David Howells
2026-11-03 12:03   ` Jarkko Sakkinen
2026-11-03 14:00     ` David Howells
2026-11-03 15:06       ` Jarkko Sakkinen
2026-11-03 15:32         ` David Howells
2026-11-03 16:58           ` Jarkko Sakkinen
2026-11-04  0:30             ` Jarkko Sakkinen

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=sashiko-outbox-196565@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dhowells@redhat.com \
    --cc=dmitry.kasatkin@gmail.com \
    --cc=ebiggers@kernel.org \
    --cc=eric.snowberg@oracle.com \
    --cc=jarkko@kernel.org \
    --cc=jmorris@namei.org \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=paul@paul-moore.com \
    --cc=roberto.sassu@huawei.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=serge@hallyn.com \
    --cc=zohar@linux.ibm.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.