From: Greg Kroah-Hartman Date: Mon, 13 Apr 2026 12:39:08 +0000 (+0200) Subject: 6.12-stable patches X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=defbda1c59fb3ffdca7a653b2aa824f663f1732f;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches 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 --- 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 index 0000000000..0c9f7df317 --- /dev/null +++ b/queue-6.12/rxrpc-fix-anonymous-key-handling.patch @@ -0,0 +1,50 @@ +From 6a59d84b4fc2f27f7b40e348506cc686712e260b Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Wed, 8 Apr 2026 13:12:31 +0100 +Subject: rxrpc: Fix anonymous key handling + +From: David Howells + +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 +cc: Marc Dionne +cc: Jeffrey Altman +cc: Simon Horman +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..a6b9d02ac1 --- /dev/null +++ b/queue-6.12/rxrpc-fix-call-removal-to-use-rcu-safe-deletion.patch @@ -0,0 +1,101 @@ +From 146d4ab94cf129ee06cd467cb5c71368a6b5bad6 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Wed, 8 Apr 2026 13:12:32 +0100 +Subject: rxrpc: Fix call removal to use RCU safe deletion + +From: David Howells + +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 +cc: Marc Dionne +cc: Jeffrey Altman +cc: Linus Torvalds +cc: Simon Horman +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..00fcac1296 --- /dev/null +++ b/queue-6.12/rxrpc-fix-key-keyring-checks-in-setsockopt-rxrpc_security_key-keyring.patch @@ -0,0 +1,87 @@ +From 2afd86ccbb2082a3c4258aea8c07e5bb6267bc2f Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Wed, 8 Apr 2026 13:12:43 +0100 +Subject: rxrpc: Fix key/keyring checks in setsockopt(RXRPC_SECURITY_KEY/KEYRING) + +From: David Howells + +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 +cc: Marc Dionne +cc: Anderson Nascimento +cc: Luxiao Xu +cc: Yuan Tan +cc: Simon Horman +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..4eb18052a5 --- /dev/null +++ b/queue-6.12/rxrpc-fix-key-reference-count-leak-from-call-key.patch @@ -0,0 +1,52 @@ +From d666540d217e8d420544ebdfbadeedd623562733 Mon Sep 17 00:00:00 2001 +From: Anderson Nascimento +Date: Wed, 8 Apr 2026 13:12:36 +0100 +Subject: rxrpc: Fix key reference count leak from call->key + +From: Anderson Nascimento + +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 +Co-developed-by: David Howells +Signed-off-by: David Howells +Reviewed-by: Jeffrey Altman +cc: Marc Dionne +cc: Simon Horman +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..4a85158978 --- /dev/null +++ b/queue-6.12/rxrpc-fix-missing-error-checks-for-rxkad-encryption-decryption-failure.patch @@ -0,0 +1,203 @@ +From f93af41b9f5f798823d0d0fb8765c2a936d76270 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Wed, 8 Apr 2026 13:12:44 +0100 +Subject: rxrpc: Fix missing error checks for rxkad encryption/decryption failure + +From: David Howells + +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 +cc: Marc Dionne +cc: Jeffrey Altman +cc: Simon Horman +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..e08dd40c72 --- /dev/null +++ b/queue-6.12/rxrpc-fix-reference-count-leak-in-rxrpc_server_keyring.patch @@ -0,0 +1,45 @@ +From f125846ee79fcae537a964ce66494e96fa54a6de Mon Sep 17 00:00:00 2001 +From: Luxiao Xu +Date: Wed, 8 Apr 2026 13:12:42 +0100 +Subject: rxrpc: fix reference count leak in rxrpc_server_keyring() + +From: Luxiao Xu + +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 +Reported-by: Juefei Pu +Co-developed-by: Yuan Tan +Signed-off-by: Yuan Tan +Suggested-by: Xin Liu +Tested-by: Ren Wei +Signed-off-by: Luxiao Xu +Signed-off-by: Ren Wei +Signed-off-by: David Howells +cc: Marc Dionne +cc: Simon Horman +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..fc9f4c7ab4 --- /dev/null +++ b/queue-6.12/rxrpc-only-put-the-call-ref-if-one-was-acquired.patch @@ -0,0 +1,53 @@ +From 6331f1b24a3e85465f6454e003a3e6c22005a5c5 Mon Sep 17 00:00:00 2001 +From: Douya Le +Date: Wed, 8 Apr 2026 13:12:38 +0100 +Subject: rxrpc: Only put the call ref if one was acquired + +From: Douya Le + +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 +Reported-by: Juefei Pu +Signed-off-by: Douya Le +Co-developed-by: Yuan Tan +Signed-off-by: Yuan Tan +Suggested-by: Xin Liu +Signed-off-by: Ao Zhou +Signed-off-by: David Howells +cc: Marc Dionne +cc: Simon Horman +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..40bc4bf429 --- /dev/null +++ b/queue-6.12/rxrpc-reject-undecryptable-rxkad-response-tickets.patch @@ -0,0 +1,64 @@ +From fe4447cd95623b1cfacc15f280aab73a6d7340b2 Mon Sep 17 00:00:00 2001 +From: Yuqi Xu +Date: Wed, 8 Apr 2026 13:12:39 +0100 +Subject: rxrpc: reject undecryptable rxkad response tickets + +From: Yuqi Xu + +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 +Reported-by: Juefei Pu +Co-developed-by: Yuan Tan +Signed-off-by: Yuan Tan +Suggested-by: Xin Liu +Tested-by: Ren Wei +Signed-off-by: Yuqi Xu +Signed-off-by: Ren Wei +Signed-off-by: David Howells +cc: Marc Dionne +cc: Simon Horman +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-6.12/series b/queue-6.12/series index e29ceaeb5c..0c8fdb2846 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -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