CVE-2026-45988
Description
In the Linux kernel, the following vulnerability has been resolved:
rxrpc: Fix re-decryption of RESPONSE packets
If a RESPONSE packet gets a temporary failure during processing, it may end up in a partially decrypted state - and then get requeued for a retry.
Fix this by just discarding the packet; we will send another CHALLENGE packet and thereby elicit a further response. Similarly, discard an incoming CHALLENGE packet if we get an error whilst generating a RESPONSE; the server will send another CHALLENGE.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Linux kernel rxrpc: DISCARD partially decrypted RESPONSE/CHALLENGE packets on temporary failure to avoid re-decryption errors.
Vulnerability
In the Linux kernel rxrpc (AF_RXRPC) network protocol implementation, a RESPONSE packet that encounters a temporary failure during processing may remain in a partially decrypted state. When such a packet is requeued for a retry, re-decryption can lead to incorrect behavior. The same issue exists for an incoming CHALLENGE packet if an error occurs during the generation of a RESPONSE. The fix discards the packet in these cases, forcing the peer to send a new CHALLENGE. The affected versions are those prior to the commit f55b383070170e988e4dec28be2af1714d258521 introduced in the stable kernel tree. [1]
Exploitation
An attacker would need to be able to inject or cause temporary failures in the processing of rxrpc RESPONSE or CHALLENGE packets on a vulnerable system. This likely requires network access to trigger the race or error condition, but no specific authentication is mentioned. The sequence involves causing a temporary failure on a RESPONSE packet, leading to partial decryption, after which the packet is requeued for retry. [1]
Impact
Successful exploitation may lead to incorrect decryption state, potentially causing denial of service or unpredictable behavior in the rxrpc connection. The fix prevents re-decryption errors, but the exact impact of the partial decryption state is not fully detailed in the provided references. [1]
Mitigation
The fix is applied in Linux kernel commit f55b383070170e988e4dec28be2af1714d258521. Users should update to a kernel version containing this commit or apply the patch. No specific workarounds are mentioned, and the CVE is not listed on CISA KEV as of the available references. [1]
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
1076cb9a2d2522rxrpc: Fix re-decryption of RESPONSE packets
2 files changed · +2 −14
include/trace/events/rxrpc.h+0 −1 modifieddiff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 13b9d017f8e177..573f2df3a2c998 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -285,7 +285,6 @@ EM(rxrpc_conn_put_unidle, "PUT unidle ") \ EM(rxrpc_conn_put_work, "PUT work ") \ EM(rxrpc_conn_queue_challenge, "QUE chall ") \ - EM(rxrpc_conn_queue_retry_work, "QUE retry-wk") \ EM(rxrpc_conn_queue_rx_work, "QUE rx-work ") \ EM(rxrpc_conn_see_new_service_conn, "SEE new-svc ") \ EM(rxrpc_conn_see_reap_service, "SEE reap-svc") \
net/rxrpc/conn_event.c+2 −13 modifieddiff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index aee977291d90bd..a2130d25aaa9b7 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c @@ -389,7 +389,6 @@ again: static void rxrpc_do_process_connection(struct rxrpc_connection *conn) { struct sk_buff *skb; - int ret; if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) rxrpc_secure_connection(conn); @@ -398,17 +397,8 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn) * connection that each one has when we've finished with it */ while ((skb = skb_dequeue(&conn->rx_queue))) { rxrpc_see_skb(skb, rxrpc_skb_see_conn_work); - ret = rxrpc_process_event(conn, skb); - switch (ret) { - case -ENOMEM: - case -EAGAIN: - skb_queue_head(&conn->rx_queue, skb); - rxrpc_queue_conn(conn, rxrpc_conn_queue_retry_work); - break; - default: - rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); - break; - } + rxrpc_process_event(conn, skb); + rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); } } -- cgit 1.3-korg
d61482be4aaerxrpc: Fix re-decryption of RESPONSE packets
2 files changed · +2 −14
include/trace/events/rxrpc.h+0 −1 modifieddiff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 2da9fbd5c5a323..539801f8ee2822 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -232,7 +232,6 @@ EM(rxrpc_conn_put_unidle, "PUT unidle ") \ EM(rxrpc_conn_put_work, "PUT work ") \ EM(rxrpc_conn_queue_challenge, "QUE chall ") \ - EM(rxrpc_conn_queue_retry_work, "QUE retry-wk") \ EM(rxrpc_conn_queue_rx_work, "QUE rx-work ") \ EM(rxrpc_conn_see_new_service_conn, "SEE new-svc ") \ EM(rxrpc_conn_see_reap_service, "SEE reap-svc") \
net/rxrpc/conn_event.c+2 −13 modifieddiff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index 6ef2dc1aa8cc2d..82cc72123c9c9f 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c @@ -344,7 +344,6 @@ again: static void rxrpc_do_process_connection(struct rxrpc_connection *conn) { struct sk_buff *skb; - int ret; if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) rxrpc_secure_connection(conn); @@ -353,17 +352,8 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn) * connection that each one has when we've finished with it */ while ((skb = skb_dequeue(&conn->rx_queue))) { rxrpc_see_skb(skb, rxrpc_skb_see_conn_work); - ret = rxrpc_process_event(conn, skb); - switch (ret) { - case -ENOMEM: - case -EAGAIN: - skb_queue_head(&conn->rx_queue, skb); - rxrpc_queue_conn(conn, rxrpc_conn_queue_retry_work); - break; - default: - rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); - break; - } + rxrpc_process_event(conn, skb); + rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); } } -- cgit 1.3-korg
7b8986830505rxrpc: Fix re-decryption of RESPONSE packets
2 files changed · +2 −14
include/trace/events/rxrpc.h+0 −1 modifieddiff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 0348d1d20cf874..ec4cabc3e730d6 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -236,7 +236,6 @@ EM(rxrpc_conn_put_unidle, "PUT unidle ") \ EM(rxrpc_conn_put_work, "PUT work ") \ EM(rxrpc_conn_queue_challenge, "QUE chall ") \ - EM(rxrpc_conn_queue_retry_work, "QUE retry-wk") \ EM(rxrpc_conn_queue_rx_work, "QUE rx-work ") \ EM(rxrpc_conn_see_new_service_conn, "SEE new-svc ") \ EM(rxrpc_conn_see_reap_service, "SEE reap-svc") \
net/rxrpc/conn_event.c+2 −13 modifieddiff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index 6ef2dc1aa8cc2d..82cc72123c9c9f 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c @@ -344,7 +344,6 @@ again: static void rxrpc_do_process_connection(struct rxrpc_connection *conn) { struct sk_buff *skb; - int ret; if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) rxrpc_secure_connection(conn); @@ -353,17 +352,8 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn) * connection that each one has when we've finished with it */ while ((skb = skb_dequeue(&conn->rx_queue))) { rxrpc_see_skb(skb, rxrpc_skb_see_conn_work); - ret = rxrpc_process_event(conn, skb); - switch (ret) { - case -ENOMEM: - case -EAGAIN: - skb_queue_head(&conn->rx_queue, skb); - rxrpc_queue_conn(conn, rxrpc_conn_queue_retry_work); - break; - default: - rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); - break; - } + rxrpc_process_event(conn, skb); + rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); } } -- cgit 1.3-korg
f55b38307017rxrpc: Fix re-decryption of RESPONSE packets
2 files changed · +2 −14
include/trace/events/rxrpc.h+0 −1 modifieddiff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 13b9d017f8e177..573f2df3a2c998 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -285,7 +285,6 @@ EM(rxrpc_conn_put_unidle, "PUT unidle ") \ EM(rxrpc_conn_put_work, "PUT work ") \ EM(rxrpc_conn_queue_challenge, "QUE chall ") \ - EM(rxrpc_conn_queue_retry_work, "QUE retry-wk") \ EM(rxrpc_conn_queue_rx_work, "QUE rx-work ") \ EM(rxrpc_conn_see_new_service_conn, "SEE new-svc ") \ EM(rxrpc_conn_see_reap_service, "SEE reap-svc") \
net/rxrpc/conn_event.c+2 −13 modifieddiff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index aee977291d90bd..a2130d25aaa9b7 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c @@ -389,7 +389,6 @@ again: static void rxrpc_do_process_connection(struct rxrpc_connection *conn) { struct sk_buff *skb; - int ret; if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) rxrpc_secure_connection(conn); @@ -398,17 +397,8 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn) * connection that each one has when we've finished with it */ while ((skb = skb_dequeue(&conn->rx_queue))) { rxrpc_see_skb(skb, rxrpc_skb_see_conn_work); - ret = rxrpc_process_event(conn, skb); - switch (ret) { - case -ENOMEM: - case -EAGAIN: - skb_queue_head(&conn->rx_queue, skb); - rxrpc_queue_conn(conn, rxrpc_conn_queue_retry_work); - break; - default: - rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); - break; - } + rxrpc_process_event(conn, skb); + rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); } } -- cgit 1.3-korg
0422e7a4883frxrpc: Fix re-decryption of RESPONSE packets
2 files changed · +2 −14
include/trace/events/rxrpc.h+0 −1 modifieddiff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 13b9d017f8e177..573f2df3a2c998 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -285,7 +285,6 @@ EM(rxrpc_conn_put_unidle, "PUT unidle ") \ EM(rxrpc_conn_put_work, "PUT work ") \ EM(rxrpc_conn_queue_challenge, "QUE chall ") \ - EM(rxrpc_conn_queue_retry_work, "QUE retry-wk") \ EM(rxrpc_conn_queue_rx_work, "QUE rx-work ") \ EM(rxrpc_conn_see_new_service_conn, "SEE new-svc ") \ EM(rxrpc_conn_see_reap_service, "SEE reap-svc") \
net/rxrpc/conn_event.c+2 −13 modifieddiff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index aee977291d90bd..a2130d25aaa9b7 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c @@ -389,7 +389,6 @@ again: static void rxrpc_do_process_connection(struct rxrpc_connection *conn) { struct sk_buff *skb; - int ret; if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) rxrpc_secure_connection(conn); @@ -398,17 +397,8 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn) * connection that each one has when we've finished with it */ while ((skb = skb_dequeue(&conn->rx_queue))) { rxrpc_see_skb(skb, rxrpc_skb_see_conn_work); - ret = rxrpc_process_event(conn, skb); - switch (ret) { - case -ENOMEM: - case -EAGAIN: - skb_queue_head(&conn->rx_queue, skb); - rxrpc_queue_conn(conn, rxrpc_conn_queue_retry_work); - break; - default: - rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); - break; - } + rxrpc_process_event(conn, skb); + rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); } } -- cgit 1.3-korg
0422e7a4883frxrpc: Fix re-decryption of RESPONSE packets
2 files changed · +2 −14
include/trace/events/rxrpc.h+0 −1 modifieddiff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 13b9d017f8e177..573f2df3a2c998 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -285,7 +285,6 @@ EM(rxrpc_conn_put_unidle, "PUT unidle ") \ EM(rxrpc_conn_put_work, "PUT work ") \ EM(rxrpc_conn_queue_challenge, "QUE chall ") \ - EM(rxrpc_conn_queue_retry_work, "QUE retry-wk") \ EM(rxrpc_conn_queue_rx_work, "QUE rx-work ") \ EM(rxrpc_conn_see_new_service_conn, "SEE new-svc ") \ EM(rxrpc_conn_see_reap_service, "SEE reap-svc") \
net/rxrpc/conn_event.c+2 −13 modifieddiff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index aee977291d90bd..a2130d25aaa9b7 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c @@ -389,7 +389,6 @@ again: static void rxrpc_do_process_connection(struct rxrpc_connection *conn) { struct sk_buff *skb; - int ret; if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) rxrpc_secure_connection(conn); @@ -398,17 +397,8 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn) * connection that each one has when we've finished with it */ while ((skb = skb_dequeue(&conn->rx_queue))) { rxrpc_see_skb(skb, rxrpc_skb_see_conn_work); - ret = rxrpc_process_event(conn, skb); - switch (ret) { - case -ENOMEM: - case -EAGAIN: - skb_queue_head(&conn->rx_queue, skb); - rxrpc_queue_conn(conn, rxrpc_conn_queue_retry_work); - break; - default: - rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); - break; - } + rxrpc_process_event(conn, skb); + rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); } } -- cgit 1.3-korg
76cb9a2d2522rxrpc: Fix re-decryption of RESPONSE packets
2 files changed · +2 −14
include/trace/events/rxrpc.h+0 −1 modifieddiff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 13b9d017f8e177..573f2df3a2c998 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -285,7 +285,6 @@ EM(rxrpc_conn_put_unidle, "PUT unidle ") \ EM(rxrpc_conn_put_work, "PUT work ") \ EM(rxrpc_conn_queue_challenge, "QUE chall ") \ - EM(rxrpc_conn_queue_retry_work, "QUE retry-wk") \ EM(rxrpc_conn_queue_rx_work, "QUE rx-work ") \ EM(rxrpc_conn_see_new_service_conn, "SEE new-svc ") \ EM(rxrpc_conn_see_reap_service, "SEE reap-svc") \
net/rxrpc/conn_event.c+2 −13 modifieddiff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index aee977291d90bd..a2130d25aaa9b7 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c @@ -389,7 +389,6 @@ again: static void rxrpc_do_process_connection(struct rxrpc_connection *conn) { struct sk_buff *skb; - int ret; if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) rxrpc_secure_connection(conn); @@ -398,17 +397,8 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn) * connection that each one has when we've finished with it */ while ((skb = skb_dequeue(&conn->rx_queue))) { rxrpc_see_skb(skb, rxrpc_skb_see_conn_work); - ret = rxrpc_process_event(conn, skb); - switch (ret) { - case -ENOMEM: - case -EAGAIN: - skb_queue_head(&conn->rx_queue, skb); - rxrpc_queue_conn(conn, rxrpc_conn_queue_retry_work); - break; - default: - rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); - break; - } + rxrpc_process_event(conn, skb); + rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); } } -- cgit 1.3-korg
7b8986830505rxrpc: Fix re-decryption of RESPONSE packets
2 files changed · +2 −14
include/trace/events/rxrpc.h+0 −1 modifieddiff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 0348d1d20cf874..ec4cabc3e730d6 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -236,7 +236,6 @@ EM(rxrpc_conn_put_unidle, "PUT unidle ") \ EM(rxrpc_conn_put_work, "PUT work ") \ EM(rxrpc_conn_queue_challenge, "QUE chall ") \ - EM(rxrpc_conn_queue_retry_work, "QUE retry-wk") \ EM(rxrpc_conn_queue_rx_work, "QUE rx-work ") \ EM(rxrpc_conn_see_new_service_conn, "SEE new-svc ") \ EM(rxrpc_conn_see_reap_service, "SEE reap-svc") \
net/rxrpc/conn_event.c+2 −13 modifieddiff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index 6ef2dc1aa8cc2d..82cc72123c9c9f 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c @@ -344,7 +344,6 @@ again: static void rxrpc_do_process_connection(struct rxrpc_connection *conn) { struct sk_buff *skb; - int ret; if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) rxrpc_secure_connection(conn); @@ -353,17 +352,8 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn) * connection that each one has when we've finished with it */ while ((skb = skb_dequeue(&conn->rx_queue))) { rxrpc_see_skb(skb, rxrpc_skb_see_conn_work); - ret = rxrpc_process_event(conn, skb); - switch (ret) { - case -ENOMEM: - case -EAGAIN: - skb_queue_head(&conn->rx_queue, skb); - rxrpc_queue_conn(conn, rxrpc_conn_queue_retry_work); - break; - default: - rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); - break; - } + rxrpc_process_event(conn, skb); + rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); } } -- cgit 1.3-korg
d61482be4aaerxrpc: Fix re-decryption of RESPONSE packets
2 files changed · +2 −14
include/trace/events/rxrpc.h+0 −1 modifieddiff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 2da9fbd5c5a323..539801f8ee2822 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -232,7 +232,6 @@ EM(rxrpc_conn_put_unidle, "PUT unidle ") \ EM(rxrpc_conn_put_work, "PUT work ") \ EM(rxrpc_conn_queue_challenge, "QUE chall ") \ - EM(rxrpc_conn_queue_retry_work, "QUE retry-wk") \ EM(rxrpc_conn_queue_rx_work, "QUE rx-work ") \ EM(rxrpc_conn_see_new_service_conn, "SEE new-svc ") \ EM(rxrpc_conn_see_reap_service, "SEE reap-svc") \
net/rxrpc/conn_event.c+2 −13 modifieddiff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index 6ef2dc1aa8cc2d..82cc72123c9c9f 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c @@ -344,7 +344,6 @@ again: static void rxrpc_do_process_connection(struct rxrpc_connection *conn) { struct sk_buff *skb; - int ret; if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) rxrpc_secure_connection(conn); @@ -353,17 +352,8 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn) * connection that each one has when we've finished with it */ while ((skb = skb_dequeue(&conn->rx_queue))) { rxrpc_see_skb(skb, rxrpc_skb_see_conn_work); - ret = rxrpc_process_event(conn, skb); - switch (ret) { - case -ENOMEM: - case -EAGAIN: - skb_queue_head(&conn->rx_queue, skb); - rxrpc_queue_conn(conn, rxrpc_conn_queue_retry_work); - break; - default: - rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); - break; - } + rxrpc_process_event(conn, skb); + rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); } } -- cgit 1.3-korg
f55b38307017rxrpc: Fix re-decryption of RESPONSE packets
2 files changed · +2 −14
include/trace/events/rxrpc.h+0 −1 modifieddiff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 13b9d017f8e177..573f2df3a2c998 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -285,7 +285,6 @@ EM(rxrpc_conn_put_unidle, "PUT unidle ") \ EM(rxrpc_conn_put_work, "PUT work ") \ EM(rxrpc_conn_queue_challenge, "QUE chall ") \ - EM(rxrpc_conn_queue_retry_work, "QUE retry-wk") \ EM(rxrpc_conn_queue_rx_work, "QUE rx-work ") \ EM(rxrpc_conn_see_new_service_conn, "SEE new-svc ") \ EM(rxrpc_conn_see_reap_service, "SEE reap-svc") \
net/rxrpc/conn_event.c+2 −13 modifieddiff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index aee977291d90bd..a2130d25aaa9b7 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c @@ -389,7 +389,6 @@ again: static void rxrpc_do_process_connection(struct rxrpc_connection *conn) { struct sk_buff *skb; - int ret; if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) rxrpc_secure_connection(conn); @@ -398,17 +397,8 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn) * connection that each one has when we've finished with it */ while ((skb = skb_dequeue(&conn->rx_queue))) { rxrpc_see_skb(skb, rxrpc_skb_see_conn_work); - ret = rxrpc_process_event(conn, skb); - switch (ret) { - case -ENOMEM: - case -EAGAIN: - skb_queue_head(&conn->rx_queue, skb); - rxrpc_queue_conn(conn, rxrpc_conn_queue_retry_work); - break; - default: - rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); - break; - } + rxrpc_process_event(conn, skb); + rxrpc_free_skb(skb, rxrpc_skb_put_conn_work); } } -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Incorrect retry logic in rxrpc connection event processing requeues partially-decrypted packets, leading to re-decryption of an already-decrypted packet."
Attack vector
An attacker on the network can send a crafted RESPONSE packet as part of the RxRPC security handshake. If the kernel encounters a temporary failure (e.g., -ENOMEM or -EAGAIN) while processing that packet, the old code would requeue the partially decrypted packet onto the connection's receive queue for a retry [patch_id=2660656]. On retry, the kernel would attempt to decrypt the already partially-decrypted packet again, leading to a corrupted decryption state. The same issue applies to CHALLENGE packets where an error during RESPONSE generation could leave the CHALLENGE in a bad state for retry.
Affected code
The vulnerability is in `net/rxrpc/conn_event.c` in the function `rxrpc_do_process_connection`. The trace event `rxrpc_conn_queue_retry_work` in `include/trace/events/rxrpc.h` is also removed as part of the fix [patch_id=2660656].
What the fix does
The patch removes the retry logic in `rxrpc_do_process_connection` that previously caught -ENOMEM and -EAGAIN return values from `rxrpc_process_event` and requeued the skb [patch_id=2660656]. Instead, after calling `rxrpc_process_event`, the packet is unconditionally freed via `rxrpc_free_skb`. This prevents any partially-decrypted packet from being re-processed. The protocol handles this gracefully because the kernel will send another CHALLENGE packet, eliciting a fresh RESPONSE from the peer. The corresponding tracepoint `rxrpc_conn_queue_retry_work` is also removed as it is no longer used.
Preconditions
- networkThe attacker must be able to send network packets to a system using the RxRPC protocol (e.g., AFS).
- inputThe kernel must encounter a temporary failure (e.g., memory pressure causing -ENOMEM) while processing the RESPONSE or CHALLENGE packet.
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/0422e7a4883f25101903f3e8105c0808aa5f4ce9nvd
- git.kernel.org/stable/c/76cb9a2d252274adfae6e293a292434631a7d472nvd
- git.kernel.org/stable/c/7b89868305052b94a91b708c462bc2281fa42a4anvd
- git.kernel.org/stable/c/d61482be4aae1835b78875761206241835a7510envd
- git.kernel.org/stable/c/f55b383070170e988e4dec28be2af1714d258521nvd
News mentions
0No linked articles in our index yet.