From: David Howells <dhowells@redhat.com>
To: netdev@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>,
Marc Dionne <marc.dionne@auristor.com>,
Jakub Kicinski <kuba@kernel.org>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
linux-afs@lists.infradead.org, linux-kernel@vger.kernel.org,
Jarkko Sakkinen <jarkko@kernel.org>,
Jeffrey Altman <jaltman@auristor.com>,
keyrings@vger.kernel.org
Subject: [PATCH net v8 08/12] keys: Add refcounting to user-defined key type payload
Date: Mon, 24 Aug 2026 10:16:40 +0100 [thread overview]
Message-ID: <20260824091645.415423-9-dhowells@redhat.com> (raw)
In-Reply-To: <20260824091645.415423-1-dhowells@redhat.com>
Add refcounting to user-defined key type payload so that a kernel service
wanting to use such a key can hold onto the payload without the RCU read
lock held in order that it can do an allocation without having to be
concerned with the key getting updated.
This is the first part of the fix for the AF_RXRPC challenge response
generation code.
Link: https://sashiko.dev/#/patchset/20260624163819.3017002-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Jeffrey Altman <jaltman@auristor.com>
cc: Eric Dumazet <edumazet@google.com>
cc: "David S. Miller" <davem@davemloft.net>
cc: Jakub Kicinski <kuba@kernel.org>
cc: Paolo Abeni <pabeni@redhat.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: keyrings@vger.kernel.org
---
include/keys/user-type.h | 10 +++++++---
net/dns_resolver/dns_key.c | 1 +
security/keys/user_defined.c | 23 ++++++++++++++++-------
3 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/include/keys/user-type.h b/include/keys/user-type.h
index 386c31432789..63846439596b 100644
--- a/include/keys/user-type.h
+++ b/include/keys/user-type.h
@@ -13,19 +13,22 @@
#ifdef CONFIG_KEYS
-/*****************************************************************************/
/*
* the payload for a key of type "user" or "logon"
* - once filled in and attached to a key:
* - the payload struct is invariant may not be changed, only replaced
- * - the payload must be read with RCU procedures or with the key semaphore
- * held
+ * - To access the payload, the caller must be holding the key semaphore or
+ * the RCU read lock or must have first taken a ref on the payload.
+ * - a ref may be taken on the payload only if the RCU read lock or key
+ * semaphore is held. refcount_inc_not_zero() needs to be used to get the
+ * ref under RCU.
* - the payload may only be replaced with the key semaphore write-locked
* - the key's data length is the size of the actual data, not including the
* payload wrapper
*/
struct user_key_payload {
struct rcu_head rcu; /* RCU destructor */
+ refcount_t ref; /* Reference count */
unsigned short datalen; /* length of this data */
char data[] __aligned(__alignof__(u64)); /* actual data */
};
@@ -37,6 +40,7 @@ struct key_preparsed_payload;
extern int user_preparse(struct key_preparsed_payload *prep);
extern void user_free_preparse(struct key_preparsed_payload *prep);
+void put_user_key_payload(struct user_key_payload *payload);
extern int user_update(struct key *key, struct key_preparsed_payload *prep);
extern void user_revoke(struct key *key);
extern void user_destroy(struct key *key);
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index 451247864a63..2bd3fb3c19f1 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -208,6 +208,7 @@ dns_resolver_preparse(struct key_preparsed_payload *prep)
kleave(" = -ENOMEM");
return -ENOMEM;
}
+ refcount_set(&upayload->ref, 1);
upayload->datalen = result_len;
memcpy(upayload->data, data, result_len);
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 6f88b507f927..55d5ed97b36e 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -67,6 +67,7 @@ int user_preparse(struct key_preparsed_payload *prep)
upayload = kmalloc_flex(*upayload, data, datalen);
if (!upayload)
return -ENOMEM;
+ refcount_set(&upayload->ref, 1);
/* attach the data */
prep->quotalen = datalen;
@@ -88,12 +89,22 @@ EXPORT_SYMBOL_GPL(user_free_preparse);
static void user_free_payload_rcu(struct rcu_head *head)
{
- struct user_key_payload *payload;
+ struct user_key_payload *payload =
+ container_of(head, struct user_key_payload, rcu);
- payload = container_of(head, struct user_key_payload, rcu);
kfree_sensitive(payload);
}
+/*
+ * Drop a ref to a user defined key payload, freeing it once all refs are gone.
+ */
+void put_user_key_payload(struct user_key_payload *payload)
+{
+ if (payload && refcount_dec_and_test(&payload->ref))
+ call_rcu(&payload->rcu, user_free_payload_rcu);
+}
+EXPORT_SYMBOL_GPL(put_user_key_payload);
+
/*
* update a user defined key
* - the key's semaphore is write-locked
@@ -115,8 +126,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)
rcu_assign_keypointer(key, prep->payload.data[0]);
prep->payload.data[0] = NULL;
- if (zap)
- call_rcu(&zap->rcu, user_free_payload_rcu);
+ put_user_key_payload(zap);
return ret;
}
EXPORT_SYMBOL_GPL(user_update);
@@ -134,7 +144,7 @@ void user_revoke(struct key *key)
if (upayload) {
rcu_assign_keypointer(key, NULL);
- call_rcu(&upayload->rcu, user_free_payload_rcu);
+ put_user_key_payload(upayload);
}
}
@@ -147,9 +157,8 @@ void user_destroy(struct key *key)
{
struct user_key_payload *upayload = key->payload.data[0];
- kfree_sensitive(upayload);
+ put_user_key_payload(upayload);
}
-
EXPORT_SYMBOL_GPL(user_destroy);
/*
next prev parent reply other threads:[~2026-08-24 9:17 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-24 9:16 [PATCH net v8 00/12] rxrpc: Fix CHALLENGE packet handling David Howells
2026-08-24 9:16 ` [PATCH net v8 01/12] rxrpc: Fix sendmsg to not return an error if last packet queued David Howells
2026-08-24 9:16 ` [PATCH net v8 02/12] rxrpc: Fix sendmsg length David Howells
2026-08-24 9:16 ` [PATCH net v8 03/12] rxrpc: Fix packet encryption error handling David Howells
2026-08-24 9:16 ` [PATCH net v8 04/12] rxrpc: Fix update of call->tx_pending without holding lock David Howells
2026-08-24 9:16 ` [PATCH net v8 05/12] rxrpc: Fix double IRQ enablement David Howells
2026-08-24 9:16 ` [PATCH net v8 06/12] rxrpc: Fix generation of notifications after call completion David Howells
2026-08-24 9:16 ` [PATCH net v8 07/12] rxrpc: Expand abort trace enum David Howells
2026-08-24 9:16 ` David Howells [this message]
2026-08-24 9:16 ` [PATCH net v8 09/12] afs: Create a server appdata key David Howells
2026-08-24 9:16 ` [PATCH net v8 10/12] rxrpc: Pass appdata key to rxrpc_call and thence to rxrpc_bundle David Howells
2026-08-24 9:16 ` [PATCH net v8 11/12] rxrpc: Fix CHALLENGE packet overqueuing and simplify RESPONSE generation David Howells
2026-08-24 9:16 ` [PATCH net v8 12/12] rxrpc: Remove OOB challenge/response code David Howells
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=20260824091645.415423-9-dhowells@redhat.com \
--to=dhowells@redhat.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jaltman@auristor.com \
--cc=jarkko@kernel.org \
--cc=keyrings@vger.kernel.org \
--cc=kuba@kernel.org \
--cc=linux-afs@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=marc.dionne@auristor.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®