All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jarkko Sakkinen <jarkko@kernel.org>
To: David Howells <dhowells@redhat.com>
Cc: Jarkko Sakkinen <jarkko@kernel.org>,
	keyrings@vger.kernel.org, linux-afs@lists.infradead.org,
	linux-cifs@vger.kernel.org, linux-integrity@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-nfs@vger.kernel.org,
	linux-s390@vger.kernel.org,
	linux-security-module@vger.kernel.org, netdev@vger.kernel.org,
	Alexander Gordeev <agordeev@linux.ibm.com>,
	Anna Schumaker <anna@kernel.org>,
	Bharath SM <bharathsm@microsoft.com>,
	Christian Borntraeger <borntraeger@linux.ibm.com>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Biggers <ebiggers@kernel.org>,
	Eric Dumazet <edumazet@kernel.org>,
	Heiko Carstens <hca@linux.ibm.com>,
	Jakub Kicinski <kuba@kernel.org>,
	James Bottomley <James.Bottomley@HansenPartnership.com>,
	James Morris <jmorris@namei.org>,
	Marc Dionne <marc.dionne@auristor.com>,
	Mimi Zohar <zohar@linux.ibm.com>,
	Namjae Jeon <linkinjeon@kernel.org>,
	Paolo Abeni <pabeni@redhat.com>, Paul Moore <paul@paul-moore.com>,
	Paulo Alcantara <pc@manguebit.org>,
	Ronnie Sahlberg <ronniesahlberg@gmail.com>,
	"Serge E. Hallyn" <serge@hallyn.com>,
	Shyam Prasad N <sprasad@microsoft.com>,
	Simon Horman <horms@kernel.org>,
	Sumit Garg <sumit.garg@kernel.org>,
	Sven Schnelle <svens@linux.ibm.com>, Tom Talpey <tom@talpey.com>,
	Trond Myklebust <trondmy@kernel.org>,
	Vasily Gorbik <gor@linux.ibm.com>
Subject: [PATCH v5 01/12] KEYS: Add key_gc_flush() for draining RCU callbacks
Date: Mon,  9 Nov 2026 00:27:07 +0200	[thread overview]
Message-ID: <20261108222719.304712-2-jarkko@kernel.org> (raw)
In-Reply-To: <20261108222719.304712-1-jarkko@kernel.org>

keyring_clear() and key_invalidate() release keyring links via call_rcu(),
and key_put() defers final key destruction to key_gc_work.

Once keys pin their type, callers that clear an internal cache before
module unload need a synchronous barrier so module references can be
dropped before delete_module() checks the refcount.

Add key_gc_flush() for flushing the remaining key_gc_work passes.

Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
 include/linux/key.h      |  2 ++
 security/keys/gc.c       | 21 +++++++++++++++++----
 security/keys/internal.h |  1 +
 security/keys/key.c      |  6 +++++-
 4 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/include/linux/key.h b/include/linux/key.h
index 420412aab926..0f408255f740 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -439,6 +439,7 @@ extern int restrict_link_reject(struct key *keyring,
 				struct key *restriction_key);
 
 extern int keyring_clear(struct key *keyring);
+void key_gc_flush(void);
 
 extern key_ref_t keyring_search(key_ref_t keyring,
 				struct key_type *type,
@@ -526,6 +527,7 @@ extern void key_init(void);
 #define key_free_user_ns(ns)		do { } while(0)
 #define key_remove_domain(d)		do { } while(0)
 #define key_lookup(k)			NULL
+#define key_gc_flush()			do { } while (0)
 
 #endif /* CONFIG_KEYS */
 #endif /* __KERNEL__ */
diff --git a/security/keys/gc.c b/security/keys/gc.c
index eda445f815d4..9b625436d3b5 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -19,8 +19,21 @@ unsigned key_gc_delay = 5 * 60;
  * Reaper for unused keys.
  */
 static void key_garbage_collector(struct work_struct *work);
+
+struct workqueue_struct *key_gc_wq __ro_after_init;
 DECLARE_WORK(key_gc_work, key_garbage_collector);
 
+/**
+ * key_gc_flush - Drain the garbage collector RCU callbacks
+ */
+void key_gc_flush(void)
+{
+	do {
+		rcu_barrier();
+	} while (flush_work(&key_gc_work));
+}
+EXPORT_SYMBOL_GPL(key_gc_flush);
+
 /*
  * Reaper for links from keyrings to dead keys.
  */
@@ -57,7 +70,7 @@ void key_schedule_gc(time64_t gc_at)
 
 	if (gc_at <= now || test_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags)) {
 		kdebug("IMMEDIATE");
-		schedule_work(&key_gc_work);
+		queue_work(key_gc_wq, &key_gc_work);
 	} else if (gc_at < key_gc_next_run) {
 		kdebug("DEFERRED");
 		key_gc_next_run = gc_at;
@@ -85,7 +98,7 @@ void key_set_expiry(struct key *key, time64_t expiry)
 void key_schedule_gc_links(void)
 {
 	set_bit(KEY_GC_KEY_EXPIRED, &key_gc_flags);
-	schedule_work(&key_gc_work);
+	queue_work(key_gc_wq, &key_gc_work);
 }
 
 /*
@@ -119,7 +132,7 @@ void key_gc_keytype(struct key_type *ktype)
 	set_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags);
 
 	kdebug("schedule");
-	schedule_work(&key_gc_work);
+	queue_work(key_gc_wq, &key_gc_work);
 
 	kdebug("sleep");
 	wait_on_bit(&key_gc_flags, KEY_GC_REAPING_KEYTYPE,
@@ -322,7 +335,7 @@ static void key_garbage_collector(struct work_struct *work)
 	}
 
 	if (gc_state & KEY_GC_REAP_AGAIN)
-		schedule_work(&key_gc_work);
+		queue_work(key_gc_wq, &key_gc_work);
 	kleave(" [end %x]", gc_state);
 	return;
 
diff --git a/security/keys/internal.h b/security/keys/internal.h
index b7b622bc36a1..84f14307552b 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -164,6 +164,7 @@ extern void key_change_session_keyring(struct callback_head *twork);
 
 extern struct work_struct key_gc_work;
 extern unsigned key_gc_delay;
+extern struct workqueue_struct *key_gc_wq;
 extern void keyring_gc(struct key *keyring, time64_t limit);
 extern void keyring_restriction_gc(struct key *keyring,
 				   struct key_type *dead_type);
diff --git a/security/keys/key.c b/security/keys/key.c
index 3f1f0fc13710..3e604d25d35e 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -670,7 +670,7 @@ void key_put(struct key *key)
 			}
 			/* Mark key as safe for GC after key->user done. */
 			clear_bit_unlock(KEY_FLAG_USER_ALIVE, &key->flags);
-			schedule_work(&key_gc_work);
+			queue_work(key_gc_wq, &key_gc_work);
 		}
 	}
 }
@@ -1294,6 +1294,10 @@ void __init key_init(void)
 	key_jar = kmem_cache_create("key_jar", sizeof(struct key),
 			0, SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_NO_MERGE, NULL);
 
+	key_gc_wq = alloc_workqueue("key_gc", WQ_MEM_RECLAIM | WQ_PERCPU, 0);
+	if (!key_gc_wq)
+		panic("Cannot create key_gc workqueue\n");
+
 	/* add the special key types */
 	list_add_tail(&key_type_keyring.link, &key_types_list);
 	list_add_tail(&key_type_dead.link, &key_types_list);
-- 
2.47.3


  reply	other threads:[~2026-11-08 22:27 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-08 22:27 [PATCH v5 00/12] KEYS: Sanitize the garbage collector Jarkko Sakkinen
2026-11-08 22:27 ` Jarkko Sakkinen [this message]
2026-11-09 22:28   ` [PATCH v5 01/12] KEYS: Add key_gc_flush() for draining RCU callbacks sashiko-bot
2026-11-08 22:27 ` [PATCH v5 02/12] dns_resolver: Move the key type into a separate module Jarkko Sakkinen
2026-11-09 22:28   ` sashiko-bot
2026-11-08 22:27 ` [PATCH v5 03/12] NFSv4: Clear idmap keyring cache when the last client unloads Jarkko Sakkinen
2026-11-09 22:28   ` sashiko-bot
2026-11-08 22:27 ` [PATCH v5 04/12] smb: client: Clear idmap/SPNEGO caches when the last session is unloaded Jarkko Sakkinen
2026-11-09 22:28   ` sashiko-bot
2026-11-08 22:27 ` [PATCH v5 05/12] s390/cert_store: Start tracking subsystem keys Jarkko Sakkinen
2026-11-09 22:28   ` sashiko-bot
2026-11-08 22:27 ` [PATCH v5 06/12] KEYS: trusted: TEE: Synchronize session lifetime Jarkko Sakkinen
2026-11-09  6:55   ` Sumit Garg
2026-11-09 22:28   ` sashiko-bot
2026-11-09 23:13     ` Jarkko Sakkinen
2026-11-08 22:27 ` [PATCH v5 07/12] KEYS: trusted: TEE: Disable sysfs bind attributes Jarkko Sakkinen
2026-11-09  7:27   ` Sumit Garg
2026-11-09 15:16     ` Jarkko Sakkinen
2026-11-09 22:28   ` sashiko-bot
2026-11-08 22:27 ` [PATCH v5 08/12] rxrpc: Release conn->key when init_connection_security() fails Jarkko Sakkinen
2026-11-09 22:28   ` sashiko-bot
2026-11-08 22:27 ` [PATCH v5 09/12] rxrpc: Move key types to their own module Jarkko Sakkinen
2026-11-09 22:28   ` sashiko-bot
2026-11-08 22:27 ` [PATCH v5 10/12] KEYS: Pin the backing kernel module for a key type Jarkko Sakkinen
2026-11-09 22:28   ` sashiko-bot
2026-11-08 22:27 ` [PATCH v5 11/12] KEYS: Remove key_type_dead Jarkko Sakkinen
2026-11-09 22:28   ` sashiko-bot
2026-11-08 22:27 ` [PATCH v5 12/12] KEYS: key_garbage_collector(): process in chunks Jarkko Sakkinen
2026-11-09 22:28   ` sashiko-bot

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=20261108222719.304712-2-jarkko@kernel.org \
    --to=jarkko@kernel.org \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=agordeev@linux.ibm.com \
    --cc=anna@kernel.org \
    --cc=bharathsm@microsoft.com \
    --cc=borntraeger@linux.ibm.com \
    --cc=davem@davemloft.net \
    --cc=dhowells@redhat.com \
    --cc=ebiggers@kernel.org \
    --cc=edumazet@kernel.org \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=horms@kernel.org \
    --cc=jmorris@namei.org \
    --cc=keyrings@vger.kernel.org \
    --cc=kuba@kernel.org \
    --cc=linkinjeon@kernel.org \
    --cc=linux-afs@lists.infradead.org \
    --cc=linux-cifs@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=marc.dionne@auristor.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=paul@paul-moore.com \
    --cc=pc@manguebit.org \
    --cc=ronniesahlberg@gmail.com \
    --cc=serge@hallyn.com \
    --cc=sprasad@microsoft.com \
    --cc=sumit.garg@kernel.org \
    --cc=svens@linux.ibm.com \
    --cc=tom@talpey.com \
    --cc=trondmy@kernel.org \
    --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.