[RFC PATCH v3 01/11] KEYS: Add key_gc_flush() for draining RCU callbacks
From: Jarkko Sakkinen
Date: Wed Nov 04 2026 - 21:11:52 EST
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@xxxxxxxxxx>
---
include/linux/key.h | 2 ++
security/keys/gc.c | 11 +++++++++++
2 files changed, 13 insertions(+)
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..2c3eddc0443a 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -21,6 +21,17 @@ 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 - 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.
*/
--
2.47.3