]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Apr 2026 12:39:08 +0000 (14:39 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Apr 2026 12:39:08 +0000 (14:39 +0200)
added patches:
rxrpc-fix-anonymous-key-handling.patch
rxrpc-fix-call-removal-to-use-rcu-safe-deletion.patch
rxrpc-fix-key-keyring-checks-in-setsockopt-rxrpc_security_key-keyring.patch
rxrpc-fix-key-reference-count-leak-from-call-key.patch
rxrpc-fix-missing-error-checks-for-rxkad-encryption-decryption-failure.patch
rxrpc-fix-reference-count-leak-in-rxrpc_server_keyring.patch
rxrpc-only-put-the-call-ref-if-one-was-acquired.patch
rxrpc-reject-undecryptable-rxkad-response-tickets.patch

queue-6.12/rxrpc-fix-anonymous-key-handling.patch [new file with mode: 0644]
queue-6.12/rxrpc-fix-call-removal-to-use-rcu-safe-deletion.patch [new file with mode: 0644]
queue-6.12/rxrpc-fix-key-keyring-checks-in-setsockopt-rxrpc_security_key-keyring.patch [new file with mode: 0644]
queue-6.12/rxrpc-fix-key-reference-count-leak-from-call-key.patch [new file with mode: 0644]
queue-6.12/rxrpc-fix-missing-error-checks-for-rxkad-encryption-decryption-failure.patch [new file with mode: 0644]
queue-6.12/rxrpc-fix-reference-count-leak-in-rxrpc_server_keyring.patch [new file with mode: 0644]
queue-6.12/rxrpc-only-put-the-call-ref-if-one-was-acquired.patch [new file with mode: 0644]
queue-6.12/rxrpc-reject-undecryptable-rxkad-response-tickets.patch [new file with mode: 0644]
queue-6.12/series

diff --git a/queue-6.12/rxrpc-fix-anonymous-key-handling.patch b/queue-6.12/rxrpc-fix-anonymous-key-handling.patch
new file mode 100644 (file)
index 0000000..0c9f7df
--- /dev/null
@@ -0,0 +1,50 @@
+From 6a59d84b4fc2f27f7b40e348506cc686712e260b Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Apr 2026 13:12:31 +0100
+Subject: rxrpc: Fix anonymous key handling
+
+From: David Howells <dhowells@redhat.com>
+
+commit 6a59d84b4fc2f27f7b40e348506cc686712e260b upstream.
+
+In rxrpc_new_client_call_for_sendmsg(), a key with no payload is meant to
+be substituted for a NULL key pointer, but the variable this is done with
+is subsequently not used.
+
+Fix this by using "key" rather than "rx->key" when filling in the
+connection parameters.
+
+Note that this only affects direct use of AF_RXRPC; the kAFS filesystem
+doesn't use sendmsg() directly and so bypasses the issue.  Further,
+AF_RXRPC passes a NULL key in if no key is set, so using an anonymous key
+in that manner works.  Since this hasn't been noticed to this point, it
+might be better just to remove the "key" variable and the code that sets it
+- and, arguably, rxrpc_init_client_call_security() would be a better place
+to handle it.
+
+Fixes: 19ffa01c9c45 ("rxrpc: Use structs to hold connection params and protocol info")
+Closes: https://sashiko.dev/#/patchset/20260319150150.4189381-1-dhowells%40redhat.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Jeffrey Altman <jaltman@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-4-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/sendmsg.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/rxrpc/sendmsg.c
++++ b/net/rxrpc/sendmsg.c
+@@ -586,7 +586,7 @@ rxrpc_new_client_call_for_sendmsg(struct
+       memset(&cp, 0, sizeof(cp));
+       cp.local                = rx->local;
+       cp.peer                 = peer;
+-      cp.key                  = rx->key;
++      cp.key                  = key;
+       cp.security_level       = rx->min_sec_level;
+       cp.exclusive            = rx->exclusive | p->exclusive;
+       cp.upgrade              = p->upgrade;
diff --git a/queue-6.12/rxrpc-fix-call-removal-to-use-rcu-safe-deletion.patch b/queue-6.12/rxrpc-fix-call-removal-to-use-rcu-safe-deletion.patch
new file mode 100644 (file)
index 0000000..a6b9d02
--- /dev/null
@@ -0,0 +1,101 @@
+From 146d4ab94cf129ee06cd467cb5c71368a6b5bad6 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Apr 2026 13:12:32 +0100
+Subject: rxrpc: Fix call removal to use RCU safe deletion
+
+From: David Howells <dhowells@redhat.com>
+
+commit 146d4ab94cf129ee06cd467cb5c71368a6b5bad6 upstream.
+
+Fix rxrpc call removal from the rxnet->calls list to use list_del_rcu()
+rather than list_del_init() to prevent stuffing up reading
+/proc/net/rxrpc/calls from potentially getting into an infinite loop.
+
+This, however, means that list_empty() no longer works on an entry that's
+been deleted from the list, making it harder to detect prior deletion.  Fix
+this by:
+
+Firstly, make rxrpc_destroy_all_calls() only dump the first ten calls that
+are unexpectedly still on the list.  Limiting the number of steps means
+there's no need to call cond_resched() or to remove calls from the list
+here, thereby eliminating the need for rxrpc_put_call() to check for that.
+
+rxrpc_put_call() can then be fixed to unconditionally delete the call from
+the list as it is the only place that the deletion occurs.
+
+Fixes: 2baec2c3f854 ("rxrpc: Support network namespacing")
+Closes: https://sashiko.dev/#/patchset/20260319150150.4189381-1-dhowells%40redhat.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Jeffrey Altman <jaltman@auristor.com>
+cc: Linus Torvalds <torvalds@linux-foundation.org>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-5-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/trace/events/rxrpc.h |    2 +-
+ net/rxrpc/call_object.c      |   24 +++++++++---------------
+ 2 files changed, 10 insertions(+), 16 deletions(-)
+
+--- a/include/trace/events/rxrpc.h
++++ b/include/trace/events/rxrpc.h
+@@ -298,7 +298,7 @@
+       EM(rxrpc_call_see_release,              "SEE release ") \
+       EM(rxrpc_call_see_userid_exists,        "SEE u-exists") \
+       EM(rxrpc_call_see_waiting_call,         "SEE q-conn  ") \
+-      E_(rxrpc_call_see_zap,                  "SEE zap     ")
++      E_(rxrpc_call_see_still_live,           "SEE !still-l")
+ #define rxrpc_txqueue_traces \
+       EM(rxrpc_txqueue_await_reply,           "AWR") \
+--- a/net/rxrpc/call_object.c
++++ b/net/rxrpc/call_object.c
+@@ -640,11 +640,9 @@ void rxrpc_put_call(struct rxrpc_call *c
+       if (dead) {
+               ASSERTCMP(__rxrpc_call_state(call), ==, RXRPC_CALL_COMPLETE);
+-              if (!list_empty(&call->link)) {
+-                      spin_lock(&rxnet->call_lock);
+-                      list_del_init(&call->link);
+-                      spin_unlock(&rxnet->call_lock);
+-              }
++              spin_lock(&rxnet->call_lock);
++              list_del_rcu(&call->link);
++              spin_unlock(&rxnet->call_lock);
+               rxrpc_cleanup_call(call);
+       }
+@@ -728,24 +726,20 @@ void rxrpc_destroy_all_calls(struct rxrp
+       _enter("");
+       if (!list_empty(&rxnet->calls)) {
+-              spin_lock(&rxnet->call_lock);
++              int shown = 0;
+-              while (!list_empty(&rxnet->calls)) {
+-                      call = list_entry(rxnet->calls.next,
+-                                        struct rxrpc_call, link);
+-                      _debug("Zapping call %p", call);
++              spin_lock(&rxnet->call_lock);
+-                      rxrpc_see_call(call, rxrpc_call_see_zap);
+-                      list_del_init(&call->link);
++              list_for_each_entry(call, &rxnet->calls, link) {
++                      rxrpc_see_call(call, rxrpc_call_see_still_live);
+                       pr_err("Call %p still in use (%d,%s,%lx,%lx)!\n",
+                              call, refcount_read(&call->ref),
+                              rxrpc_call_states[__rxrpc_call_state(call)],
+                              call->flags, call->events);
+-                      spin_unlock(&rxnet->call_lock);
+-                      cond_resched();
+-                      spin_lock(&rxnet->call_lock);
++                      if (++shown >= 10)
++                              break;
+               }
+               spin_unlock(&rxnet->call_lock);
diff --git a/queue-6.12/rxrpc-fix-key-keyring-checks-in-setsockopt-rxrpc_security_key-keyring.patch b/queue-6.12/rxrpc-fix-key-keyring-checks-in-setsockopt-rxrpc_security_key-keyring.patch
new file mode 100644 (file)
index 0000000..00fcac1
--- /dev/null
@@ -0,0 +1,87 @@
+From 2afd86ccbb2082a3c4258aea8c07e5bb6267bc2f Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Apr 2026 13:12:43 +0100
+Subject: rxrpc: Fix key/keyring checks in setsockopt(RXRPC_SECURITY_KEY/KEYRING)
+
+From: David Howells <dhowells@redhat.com>
+
+commit 2afd86ccbb2082a3c4258aea8c07e5bb6267bc2f upstream.
+
+An AF_RXRPC socket can be both client and server at the same time.  When
+sending new calls (ie. it's acting as a client), it uses rx->key to set the
+security, and when accepting incoming calls (ie. it's acting as a server),
+it uses rx->securities.
+
+setsockopt(RXRPC_SECURITY_KEY) sets rx->key to point to an rxrpc-type key
+and setsockopt(RXRPC_SECURITY_KEYRING) sets rx->securities to point to a
+keyring of rxrpc_s-type keys.
+
+Now, it should be possible to use both rx->key and rx->securities on the
+same socket - but for userspace AF_RXRPC sockets rxrpc_setsockopt()
+prevents that.
+
+Fix this by:
+
+ (1) Remove the incorrect check rxrpc_setsockopt(RXRPC_SECURITY_KEYRING)
+     makes on rx->key.
+
+ (2) Move the check that rxrpc_setsockopt(RXRPC_SECURITY_KEY) makes on
+     rx->key down into rxrpc_request_key().
+
+ (3) Remove rxrpc_request_key()'s check on rx->securities.
+
+This (in combination with a previous patch) pushes the checks down into the
+functions that set those pointers and removes the cross-checks that prevent
+both key and keyring being set.
+
+Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
+Closes: https://sashiko.dev/#/patchset/20260401105614.1696001-10-dhowells@redhat.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Anderson Nascimento <anderson@allelesecurity.com>
+cc: Luxiao Xu <rakukuip@gmail.com>
+cc: Yuan Tan <yuantan098@gmail.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-16-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/af_rxrpc.c |    6 ------
+ net/rxrpc/key.c      |    2 +-
+ 2 files changed, 1 insertion(+), 7 deletions(-)
+
+--- a/net/rxrpc/af_rxrpc.c
++++ b/net/rxrpc/af_rxrpc.c
+@@ -681,9 +681,6 @@ static int rxrpc_setsockopt(struct socke
+                       goto success;
+               case RXRPC_SECURITY_KEY:
+-                      ret = -EINVAL;
+-                      if (rx->key)
+-                              goto error;
+                       ret = -EISCONN;
+                       if (rx->sk.sk_state != RXRPC_UNBOUND)
+                               goto error;
+@@ -691,9 +688,6 @@ static int rxrpc_setsockopt(struct socke
+                       goto error;
+               case RXRPC_SECURITY_KEYRING:
+-                      ret = -EINVAL;
+-                      if (rx->key)
+-                              goto error;
+                       ret = -EISCONN;
+                       if (rx->sk.sk_state != RXRPC_UNBOUND)
+                               goto error;
+--- a/net/rxrpc/key.c
++++ b/net/rxrpc/key.c
+@@ -452,7 +452,7 @@ int rxrpc_request_key(struct rxrpc_sock
+       _enter("");
+-      if (optlen <= 0 || optlen > PAGE_SIZE - 1 || rx->securities)
++      if (optlen <= 0 || optlen > PAGE_SIZE - 1 || rx->key)
+               return -EINVAL;
+       description = memdup_sockptr_nul(optval, optlen);
diff --git a/queue-6.12/rxrpc-fix-key-reference-count-leak-from-call-key.patch b/queue-6.12/rxrpc-fix-key-reference-count-leak-from-call-key.patch
new file mode 100644 (file)
index 0000000..4eb1805
--- /dev/null
@@ -0,0 +1,52 @@
+From d666540d217e8d420544ebdfbadeedd623562733 Mon Sep 17 00:00:00 2001
+From: Anderson Nascimento <anderson@allelesecurity.com>
+Date: Wed, 8 Apr 2026 13:12:36 +0100
+Subject: rxrpc: Fix key reference count leak from call->key
+
+From: Anderson Nascimento <anderson@allelesecurity.com>
+
+commit d666540d217e8d420544ebdfbadeedd623562733 upstream.
+
+When creating a client call in rxrpc_alloc_client_call(), the code obtains
+a reference to the key.  This is never cleaned up and gets leaked when the
+call is destroyed.
+
+Fix this by freeing call->key in rxrpc_destroy_call().
+
+Before the patch, it shows the key reference counter elevated:
+
+$ cat /proc/keys | grep afs@54321
+1bffe9cd I--Q--i 8053480 4169w 3b010000  1000  1000 rxrpc     afs@54321: ka
+$
+
+After the patch, the invalidated key is removed when the code exits:
+
+$ cat /proc/keys | grep afs@54321
+$
+
+Fixes: f3441d4125fc ("rxrpc: Copy client call parameters into rxrpc_call earlier")
+Signed-off-by: Anderson Nascimento <anderson@allelesecurity.com>
+Co-developed-by: David Howells <dhowells@redhat.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-9-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/call_object.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/rxrpc/call_object.c
++++ b/net/rxrpc/call_object.c
+@@ -690,6 +690,7 @@ static void rxrpc_destroy_call(struct wo
+       rxrpc_put_bundle(call->bundle, rxrpc_bundle_put_call);
+       rxrpc_put_peer(call->peer, rxrpc_peer_put_call);
+       rxrpc_put_local(call->local, rxrpc_local_put_call);
++      key_put(call->key);
+       call_rcu(&call->rcu, rxrpc_rcu_free_call);
+ }
diff --git a/queue-6.12/rxrpc-fix-missing-error-checks-for-rxkad-encryption-decryption-failure.patch b/queue-6.12/rxrpc-fix-missing-error-checks-for-rxkad-encryption-decryption-failure.patch
new file mode 100644 (file)
index 0000000..4a85158
--- /dev/null
@@ -0,0 +1,203 @@
+From f93af41b9f5f798823d0d0fb8765c2a936d76270 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Apr 2026 13:12:44 +0100
+Subject: rxrpc: Fix missing error checks for rxkad encryption/decryption failure
+
+From: David Howells <dhowells@redhat.com>
+
+commit f93af41b9f5f798823d0d0fb8765c2a936d76270 upstream.
+
+Add error checking for failure of crypto_skcipher_en/decrypt() to various
+rxkad function as the crypto functions can fail with ENOMEM at least.
+
+Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
+Closes: https://sashiko.dev/#/patchset/20260401105614.1696001-10-dhowells@redhat.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Jeffrey Altman <jaltman@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-17-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/rxkad.c |   57 ++++++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 38 insertions(+), 19 deletions(-)
+
+--- a/net/rxrpc/rxkad.c
++++ b/net/rxrpc/rxkad.c
+@@ -189,6 +189,7 @@ static int rxkad_prime_packet_security(s
+       struct rxrpc_crypt iv;
+       __be32 *tmpbuf;
+       size_t tmpsize = 4 * sizeof(__be32);
++      int ret;
+       _enter("");
+@@ -217,13 +218,13 @@ static int rxkad_prime_packet_security(s
+       skcipher_request_set_sync_tfm(req, ci);
+       skcipher_request_set_callback(req, 0, NULL, NULL);
+       skcipher_request_set_crypt(req, &sg, &sg, tmpsize, iv.x);
+-      crypto_skcipher_encrypt(req);
++      ret = crypto_skcipher_encrypt(req);
+       skcipher_request_free(req);
+       memcpy(&conn->rxkad.csum_iv, tmpbuf + 2, sizeof(conn->rxkad.csum_iv));
+       kfree(tmpbuf);
+-      _leave(" = 0");
+-      return 0;
++      _leave(" = %d", ret);
++      return ret;
+ }
+ /*
+@@ -257,6 +258,7 @@ static int rxkad_secure_packet_auth(cons
+       struct scatterlist sg;
+       size_t pad;
+       u16 check;
++      int ret;
+       _enter("");
+@@ -279,11 +281,11 @@ static int rxkad_secure_packet_auth(cons
+       skcipher_request_set_sync_tfm(req, call->conn->rxkad.cipher);
+       skcipher_request_set_callback(req, 0, NULL, NULL);
+       skcipher_request_set_crypt(req, &sg, &sg, 8, iv.x);
+-      crypto_skcipher_encrypt(req);
++      ret = crypto_skcipher_encrypt(req);
+       skcipher_request_zero(req);
+-      _leave(" = 0");
+-      return 0;
++      _leave(" = %d", ret);
++      return ret;
+ }
+ /*
+@@ -342,7 +344,7 @@ static int rxkad_secure_packet(struct rx
+       union {
+               __be32 buf[2];
+       } crypto __aligned(8);
+-      u32 x, y;
++      u32 x, y = 0;
+       int ret;
+       _enter("{%d{%x}},{#%u},%u,",
+@@ -373,8 +375,10 @@ static int rxkad_secure_packet(struct rx
+       skcipher_request_set_sync_tfm(req, call->conn->rxkad.cipher);
+       skcipher_request_set_callback(req, 0, NULL, NULL);
+       skcipher_request_set_crypt(req, &sg, &sg, 8, iv.x);
+-      crypto_skcipher_encrypt(req);
++      ret = crypto_skcipher_encrypt(req);
+       skcipher_request_zero(req);
++      if (ret < 0)
++              goto out;
+       y = ntohl(crypto.buf[1]);
+       y = (y >> 16) & 0xffff;
+@@ -397,6 +401,7 @@ static int rxkad_secure_packet(struct rx
+               break;
+       }
++out:
+       skcipher_request_free(req);
+       _leave(" = %d [set %x]", ret, y);
+       return ret;
+@@ -437,8 +442,10 @@ static int rxkad_verify_packet_1(struct
+       skcipher_request_set_sync_tfm(req, call->conn->rxkad.cipher);
+       skcipher_request_set_callback(req, 0, NULL, NULL);
+       skcipher_request_set_crypt(req, sg, sg, 8, iv.x);
+-      crypto_skcipher_decrypt(req);
++      ret = crypto_skcipher_decrypt(req);
+       skcipher_request_zero(req);
++      if (ret < 0)
++              return ret;
+       /* Extract the decrypted packet length */
+       if (skb_copy_bits(skb, sp->offset, &sechdr, sizeof(sechdr)) < 0)
+@@ -515,10 +522,14 @@ static int rxkad_verify_packet_2(struct
+       skcipher_request_set_sync_tfm(req, call->conn->rxkad.cipher);
+       skcipher_request_set_callback(req, 0, NULL, NULL);
+       skcipher_request_set_crypt(req, sg, sg, sp->len, iv.x);
+-      crypto_skcipher_decrypt(req);
++      ret = crypto_skcipher_decrypt(req);
+       skcipher_request_zero(req);
+       if (sg != _sg)
+               kfree(sg);
++      if (ret < 0) {
++              WARN_ON_ONCE(ret != -ENOMEM);
++              return ret;
++      }
+       /* Extract the decrypted packet length */
+       if (skb_copy_bits(skb, sp->offset, &sechdr, sizeof(sechdr)) < 0)
+@@ -586,8 +597,10 @@ static int rxkad_verify_packet(struct rx
+       skcipher_request_set_sync_tfm(req, call->conn->rxkad.cipher);
+       skcipher_request_set_callback(req, 0, NULL, NULL);
+       skcipher_request_set_crypt(req, &sg, &sg, 8, iv.x);
+-      crypto_skcipher_encrypt(req);
++      ret = crypto_skcipher_encrypt(req);
+       skcipher_request_zero(req);
++      if (ret < 0)
++              goto out;
+       y = ntohl(crypto.buf[1]);
+       cksum = (y >> 16) & 0xffff;
+@@ -989,21 +1002,23 @@ static int rxkad_decrypt_ticket(struct r
+ /*
+  * decrypt the response packet
+  */
+-static void rxkad_decrypt_response(struct rxrpc_connection *conn,
+-                                 struct rxkad_response *resp,
+-                                 const struct rxrpc_crypt *session_key)
++static int rxkad_decrypt_response(struct rxrpc_connection *conn,
++                                struct rxkad_response *resp,
++                                const struct rxrpc_crypt *session_key)
+ {
+       struct skcipher_request *req = rxkad_ci_req;
+       struct scatterlist sg[1];
+       struct rxrpc_crypt iv;
++      int ret;
+       _enter(",,%08x%08x",
+              ntohl(session_key->n[0]), ntohl(session_key->n[1]));
+       mutex_lock(&rxkad_ci_mutex);
+-      if (crypto_sync_skcipher_setkey(rxkad_ci, session_key->x,
+-                                      sizeof(*session_key)) < 0)
+-              BUG();
++      ret = crypto_sync_skcipher_setkey(rxkad_ci, session_key->x,
++                                        sizeof(*session_key));
++      if (ret < 0)
++              goto unlock;
+       memcpy(&iv, session_key, sizeof(iv));
+@@ -1012,12 +1027,14 @@ static void rxkad_decrypt_response(struc
+       skcipher_request_set_sync_tfm(req, rxkad_ci);
+       skcipher_request_set_callback(req, 0, NULL, NULL);
+       skcipher_request_set_crypt(req, sg, sg, sizeof(resp->encrypted), iv.x);
+-      crypto_skcipher_decrypt(req);
++      ret = crypto_skcipher_decrypt(req);
+       skcipher_request_zero(req);
++unlock:
+       mutex_unlock(&rxkad_ci_mutex);
+       _leave("");
++      return ret;
+ }
+ /*
+@@ -1110,7 +1127,9 @@ static int rxkad_verify_response(struct
+       /* use the session key from inside the ticket to decrypt the
+        * response */
+-      rxkad_decrypt_response(conn, response, &session_key);
++      ret = rxkad_decrypt_response(conn, response, &session_key);
++      if (ret < 0)
++              goto temporary_error_free_ticket;
+       if (ntohl(response->encrypted.epoch) != conn->proto.epoch ||
+           ntohl(response->encrypted.cid) != conn->proto.cid ||
diff --git a/queue-6.12/rxrpc-fix-reference-count-leak-in-rxrpc_server_keyring.patch b/queue-6.12/rxrpc-fix-reference-count-leak-in-rxrpc_server_keyring.patch
new file mode 100644 (file)
index 0000000..e08dd40
--- /dev/null
@@ -0,0 +1,45 @@
+From f125846ee79fcae537a964ce66494e96fa54a6de Mon Sep 17 00:00:00 2001
+From: Luxiao Xu <rakukuip@gmail.com>
+Date: Wed, 8 Apr 2026 13:12:42 +0100
+Subject: rxrpc: fix reference count leak in rxrpc_server_keyring()
+
+From: Luxiao Xu <rakukuip@gmail.com>
+
+commit f125846ee79fcae537a964ce66494e96fa54a6de upstream.
+
+This patch fixes a reference count leak in rxrpc_server_keyring()
+by checking if rx->securities is already set.
+
+Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Co-developed-by: Yuan Tan <yuantan098@gmail.com>
+Signed-off-by: Yuan Tan <yuantan098@gmail.com>
+Suggested-by: Xin Liu <bird@lzu.edu.cn>
+Tested-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-15-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/server_key.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/rxrpc/server_key.c
++++ b/net/rxrpc/server_key.c
+@@ -125,6 +125,9 @@ int rxrpc_server_keyring(struct rxrpc_so
+       _enter("");
++      if (rx->securities)
++              return -EINVAL;
++
+       if (optlen <= 0 || optlen > PAGE_SIZE - 1)
+               return -EINVAL;
diff --git a/queue-6.12/rxrpc-only-put-the-call-ref-if-one-was-acquired.patch b/queue-6.12/rxrpc-only-put-the-call-ref-if-one-was-acquired.patch
new file mode 100644 (file)
index 0000000..fc9f4c7
--- /dev/null
@@ -0,0 +1,53 @@
+From 6331f1b24a3e85465f6454e003a3e6c22005a5c5 Mon Sep 17 00:00:00 2001
+From: Douya Le <ldy3087146292@gmail.com>
+Date: Wed, 8 Apr 2026 13:12:38 +0100
+Subject: rxrpc: Only put the call ref if one was acquired
+
+From: Douya Le <ldy3087146292@gmail.com>
+
+commit 6331f1b24a3e85465f6454e003a3e6c22005a5c5 upstream.
+
+rxrpc_input_packet_on_conn() can process a to-client packet after the
+current client call on the channel has already been torn down.  In that
+case chan->call is NULL, rxrpc_try_get_call() returns NULL and there is
+no reference to drop.
+
+The client-side implicit-end error path does not account for that and
+unconditionally calls rxrpc_put_call().  This turns a protocol error
+path into a kernel crash instead of rejecting the packet.
+
+Only drop the call reference if one was actually acquired.  Keep the
+existing protocol error handling unchanged.
+
+Fixes: 5e6ef4f1017c ("rxrpc: Make the I/O thread take over the call and local processor work")
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Signed-off-by: Douya Le <ldy3087146292@gmail.com>
+Co-developed-by: Yuan Tan <tanyuan98@gmail.com>
+Signed-off-by: Yuan Tan <tanyuan98@gmail.com>
+Suggested-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Ao Zhou <n05ec@lzu.edu.cn>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-11-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/io_thread.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/rxrpc/io_thread.c
++++ b/net/rxrpc/io_thread.c
+@@ -400,7 +400,8 @@ static int rxrpc_input_packet_on_conn(st
+       if (sp->hdr.callNumber > chan->call_id) {
+               if (rxrpc_to_client(sp)) {
+-                      rxrpc_put_call(call, rxrpc_call_put_input);
++                      if (call)
++                              rxrpc_put_call(call, rxrpc_call_put_input);
+                       return rxrpc_protocol_error(skb,
+                                                   rxrpc_eproto_unexpected_implicit_end);
+               }
diff --git a/queue-6.12/rxrpc-reject-undecryptable-rxkad-response-tickets.patch b/queue-6.12/rxrpc-reject-undecryptable-rxkad-response-tickets.patch
new file mode 100644 (file)
index 0000000..40bc4bf
--- /dev/null
@@ -0,0 +1,64 @@
+From fe4447cd95623b1cfacc15f280aab73a6d7340b2 Mon Sep 17 00:00:00 2001
+From: Yuqi Xu <xuyuqiabc@gmail.com>
+Date: Wed, 8 Apr 2026 13:12:39 +0100
+Subject: rxrpc: reject undecryptable rxkad response tickets
+
+From: Yuqi Xu <xuyuqiabc@gmail.com>
+
+commit fe4447cd95623b1cfacc15f280aab73a6d7340b2 upstream.
+
+rxkad_decrypt_ticket() decrypts the RXKAD response ticket and then
+parses the buffer as plaintext without checking whether
+crypto_skcipher_decrypt() succeeded.
+
+A malformed RESPONSE can therefore use a non-block-aligned ticket
+length, make the decrypt operation fail, and still drive the ticket
+parser with attacker-controlled bytes.
+
+Check the decrypt result and abort the connection with RXKADBADTICKET
+when ticket decryption fails.
+
+Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Co-developed-by: Yuan Tan <yuantan098@gmail.com>
+Signed-off-by: Yuan Tan <yuantan098@gmail.com>
+Suggested-by: Xin Liu <bird@lzu.edu.cn>
+Tested-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-12-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/rxkad.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/net/rxrpc/rxkad.c
++++ b/net/rxrpc/rxkad.c
+@@ -870,6 +870,7 @@ static int rxkad_decrypt_ticket(struct r
+       struct in_addr addr;
+       unsigned int life;
+       time64_t issue, now;
++      int ret;
+       bool little_endian;
+       u8 *p, *q, *name, *end;
+@@ -889,8 +890,11 @@ static int rxkad_decrypt_ticket(struct r
+       sg_init_one(&sg[0], ticket, ticket_len);
+       skcipher_request_set_callback(req, 0, NULL, NULL);
+       skcipher_request_set_crypt(req, sg, sg, ticket_len, iv.x);
+-      crypto_skcipher_decrypt(req);
++      ret = crypto_skcipher_decrypt(req);
+       skcipher_request_free(req);
++      if (ret < 0)
++              return rxrpc_abort_conn(conn, skb, RXKADBADTICKET, -EPROTO,
++                                      rxkad_abort_resp_tkt_short);
+       p = ticket;
+       end = p + ticket_len;
index e29ceaeb5cf376915320be025e14afb5f020cdd2..0c8fdb2846e369460031a6201a4d04659fd8ff27 100644 (file)
@@ -58,3 +58,11 @@ idpf-set-the-payload-size-before-calling-the-async-handler.patch
 net-lan966x-fix-page_pool-error-handling-in-lan966x_fdma_rx_alloc_page_pool.patch
 net-lan966x-fix-page-pool-leak-in-error-paths.patch
 net-lan966x-fix-use-after-free-and-leak-in-lan966x_fdma_reload.patch
+rxrpc-fix-anonymous-key-handling.patch
+rxrpc-fix-call-removal-to-use-rcu-safe-deletion.patch
+rxrpc-fix-key-reference-count-leak-from-call-key.patch
+rxrpc-only-put-the-call-ref-if-one-was-acquired.patch
+rxrpc-reject-undecryptable-rxkad-response-tickets.patch
+rxrpc-fix-reference-count-leak-in-rxrpc_server_keyring.patch
+rxrpc-fix-key-keyring-checks-in-setsockopt-rxrpc_security_key-keyring.patch
+rxrpc-fix-missing-error-checks-for-rxkad-encryption-decryption-failure.patch