]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
7.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 1 May 2026 12:05:46 +0000 (14:05 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 1 May 2026 12:05:46 +0000 (14:05 +0200)
added patches:
edac-versalnet-fix-memory-leak-in-remove-and-probe-error-paths.patch
net-txgbe-fix-rtnl-assertion-warning-when-remove-module.patch
rxrpc-fix-conn-level-packet-handling-to-unshare-response-packets.patch
rxrpc-fix-error-handling-in-rxgk_extract_token.patch
rxrpc-fix-memory-leaks-in-rxkad_verify_response.patch
rxrpc-fix-potential-uaf-after-skb_unshare-failure.patch
rxrpc-fix-re-decryption-of-response-packets.patch
rxrpc-fix-rxkad-crypto-unalignment-handling.patch
rxrpc-fix-rxrpc_input_call_event-to-only-unshare-data-packets.patch
tools-accounting-handle-truncated-taskstats-netlink-messages.patch

queue-7.0/edac-versalnet-fix-memory-leak-in-remove-and-probe-error-paths.patch [new file with mode: 0644]
queue-7.0/net-txgbe-fix-rtnl-assertion-warning-when-remove-module.patch [new file with mode: 0644]
queue-7.0/rxrpc-fix-conn-level-packet-handling-to-unshare-response-packets.patch [new file with mode: 0644]
queue-7.0/rxrpc-fix-error-handling-in-rxgk_extract_token.patch [new file with mode: 0644]
queue-7.0/rxrpc-fix-memory-leaks-in-rxkad_verify_response.patch [new file with mode: 0644]
queue-7.0/rxrpc-fix-potential-uaf-after-skb_unshare-failure.patch [new file with mode: 0644]
queue-7.0/rxrpc-fix-re-decryption-of-response-packets.patch [new file with mode: 0644]
queue-7.0/rxrpc-fix-rxkad-crypto-unalignment-handling.patch [new file with mode: 0644]
queue-7.0/rxrpc-fix-rxrpc_input_call_event-to-only-unshare-data-packets.patch [new file with mode: 0644]
queue-7.0/series
queue-7.0/tools-accounting-handle-truncated-taskstats-netlink-messages.patch [new file with mode: 0644]

diff --git a/queue-7.0/edac-versalnet-fix-memory-leak-in-remove-and-probe-error-paths.patch b/queue-7.0/edac-versalnet-fix-memory-leak-in-remove-and-probe-error-paths.patch
new file mode 100644 (file)
index 0000000..406f436
--- /dev/null
@@ -0,0 +1,41 @@
+From 1b6f292cb94d95c9bc22e1efe592daf62c60bc2e Mon Sep 17 00:00:00 2001
+From: Prasanna Kumar T S M <ptsm@linux.microsoft.com>
+Date: Sun, 22 Mar 2026 06:11:39 -0700
+Subject: EDAC/versalnet: Fix memory leak in remove and probe error paths
+
+From: Prasanna Kumar T S M <ptsm@linux.microsoft.com>
+
+commit 1b6f292cb94d95c9bc22e1efe592daf62c60bc2e upstream.
+
+The mcdi object allocated using kzalloc() in the setup_mcdi() is not freed in
+the remove path or in probe's error handling path leading to a memory leak.
+Fix it by freeing the allocated memory.
+
+Fixes: d5fe2fec6c40d ("EDAC: Add a driver for the AMD Versal NET DDR controller")
+Signed-off-by: Prasanna Kumar T S M <ptsm@linux.microsoft.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260322131139.1684716-1-ptsm@linux.microsoft.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/edac/versalnet_edac.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/edac/versalnet_edac.c
++++ b/drivers/edac/versalnet_edac.c
+@@ -917,6 +917,7 @@ static int mc_probe(struct platform_devi
+ err_init:
+       cdx_mcdi_finish(priv->mcdi);
++      kfree(priv->mcdi);
+ err_unreg:
+       unregister_rpmsg_driver(&amd_rpmsg_driver);
+@@ -938,6 +939,7 @@ static void mc_remove(struct platform_de
+       remove_versalnet(priv);
+       rproc_shutdown(priv->mcdi->r5_rproc);
+       cdx_mcdi_finish(priv->mcdi);
++      kfree(priv->mcdi);
+ }
+ static const struct of_device_id amd_edac_match[] = {
diff --git a/queue-7.0/net-txgbe-fix-rtnl-assertion-warning-when-remove-module.patch b/queue-7.0/net-txgbe-fix-rtnl-assertion-warning-when-remove-module.patch
new file mode 100644 (file)
index 0000000..ebba294
--- /dev/null
@@ -0,0 +1,97 @@
+From e159f05e12cc1111a3103b99375ddf0dfd0e7d63 Mon Sep 17 00:00:00 2001
+From: Jiawen Wu <jiawenwu@trustnetic.com>
+Date: Tue, 7 Apr 2026 17:40:41 +0800
+Subject: net: txgbe: fix RTNL assertion warning when remove module
+
+From: Jiawen Wu <jiawenwu@trustnetic.com>
+
+commit e159f05e12cc1111a3103b99375ddf0dfd0e7d63 upstream.
+
+For the copper NIC with external PHY, the driver called
+phylink_connect_phy() during probe and phylink_disconnect_phy() during
+remove. It caused an RTNL assertion warning in phylink_disconnect_phy()
+upon module remove.
+
+To fix this, add rtnl_lock() and rtnl_unlock() around the
+phylink_disconnect_phy() in remove function.
+
+ ------------[ cut here ]------------
+ RTNL: assertion failed at drivers/net/phy/phylink.c (2351)
+ WARNING: drivers/net/phy/phylink.c:2351 at
+phylink_disconnect_phy+0xd8/0xf0 [phylink], CPU#0: rmmod/4464
+ Modules linked in: ...
+ CPU: 0 UID: 0 PID: 4464 Comm: rmmod Kdump: loaded Not tainted 7.0.0-rc4+
+ Hardware name: Micro-Star International Co., Ltd. MS-7E16/X670E GAMING
+PLUS WIFI (MS-7E16), BIOS 1.90 12/31/2024
+ RIP: 0010:phylink_disconnect_phy+0xe4/0xf0 [phylink]
+ Code: 5b 41 5c 41 5d 41 5e 41 5f 5d 31 c0 31 d2 31 f6 31 ff e9 3a 38 8f e7
+48 8d 3d 48 87 e2 ff ba 2f 09 00 00 48 c7 c6 c1 22 24 c0 <67> 48 0f b9 3a
+e9 34 ff ff ff 66 90 90 90 90 90 90 90 90 90 90 90
+ RSP: 0018:ffffce7288363ac0 EFLAGS: 00010246
+ RAX: 0000000000000000 RBX: ffff89654b2a1a00 RCX: 0000000000000000
+ RDX: 000000000000092f RSI: ffffffffc02422c1 RDI: ffffffffc0239020
+ RBP: ffffce7288363ae8 R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000000 R12: ffff8964c4022000
+ R13: ffff89654fce3028 R14: ffff89654ebb4000 R15: ffffffffc0226348
+ FS:  0000795e80d93780(0000) GS:ffff896c52857000(0000)
+knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00005b528b592000 CR3: 0000000170d0f000 CR4: 0000000000f50ef0
+ PKRU: 55555554
+ Call Trace:
+  <TASK>
+  txgbe_remove_phy+0xbb/0xd0 [txgbe]
+  txgbe_remove+0x4c/0xb0 [txgbe]
+  pci_device_remove+0x41/0xb0
+  device_remove+0x43/0x80
+  device_release_driver_internal+0x206/0x270
+  driver_detach+0x4a/0xa0
+  bus_remove_driver+0x83/0x120
+  driver_unregister+0x2f/0x60
+  pci_unregister_driver+0x40/0x90
+  txgbe_driver_exit+0x10/0x850 [txgbe]
+  __do_sys_delete_module.isra.0+0x1c3/0x2f0
+  __x64_sys_delete_module+0x12/0x20
+  x64_sys_call+0x20c3/0x2390
+  do_syscall_64+0x11c/0x1500
+  ? srso_alias_return_thunk+0x5/0xfbef5
+  ? do_syscall_64+0x15a/0x1500
+  ? srso_alias_return_thunk+0x5/0xfbef5
+  ? do_fault+0x312/0x580
+  ? srso_alias_return_thunk+0x5/0xfbef5
+  ? __handle_mm_fault+0x9d5/0x1040
+  ? srso_alias_return_thunk+0x5/0xfbef5
+  ? count_memcg_events+0x101/0x1d0
+  ? srso_alias_return_thunk+0x5/0xfbef5
+  ? handle_mm_fault+0x1e8/0x2f0
+  ? srso_alias_return_thunk+0x5/0xfbef5
+  ? do_user_addr_fault+0x2f8/0x820
+  ? srso_alias_return_thunk+0x5/0xfbef5
+  ? irqentry_exit+0xb2/0x600
+  ? srso_alias_return_thunk+0x5/0xfbef5
+  ? exc_page_fault+0x92/0x1c0
+  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 02b2a6f91b90 ("net: txgbe: support copper NIC with external PHY")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/8B47A5872884147D+20260407094041.4646-1-jiawenwu@trustnetic.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
+@@ -657,7 +657,9 @@ void txgbe_remove_phy(struct txgbe *txgb
+               return;
+       case wx_mac_sp:
+               if (txgbe->wx->media_type == wx_media_copper) {
++                      rtnl_lock();
+                       phylink_disconnect_phy(txgbe->wx->phylink);
++                      rtnl_unlock();
+                       phylink_destroy(txgbe->wx->phylink);
+                       return;
+               }
diff --git a/queue-7.0/rxrpc-fix-conn-level-packet-handling-to-unshare-response-packets.patch b/queue-7.0/rxrpc-fix-conn-level-packet-handling-to-unshare-response-packets.patch
new file mode 100644 (file)
index 0000000..a87b298
--- /dev/null
@@ -0,0 +1,77 @@
+From 24481a7f573305706054c59e275371f8d0fe919f Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 22 Apr 2026 17:14:33 +0100
+Subject: rxrpc: Fix conn-level packet handling to unshare RESPONSE packets
+
+From: David Howells <dhowells@redhat.com>
+
+commit 24481a7f573305706054c59e275371f8d0fe919f upstream.
+
+The security operations that verify the RESPONSE packets decrypt bits of it
+in place - however, the sk_buff may be shared with a packet sniffer, which
+would lead to the sniffer seeing an apparently corrupt packet (actually
+decrypted).
+
+Fix this by handing a copy of the packet off to the specific security
+handler if the packet was cloned.
+
+Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
+Closes: https://sashiko.dev/#/patchset/20260408121252.2249051-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/20260422161438.2593376-5-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/conn_event.c |   29 ++++++++++++++++++++++++++++-
+ 1 file changed, 28 insertions(+), 1 deletion(-)
+
+--- a/net/rxrpc/conn_event.c
++++ b/net/rxrpc/conn_event.c
+@@ -240,6 +240,33 @@ static void rxrpc_call_is_secure(struct
+               rxrpc_notify_socket(call);
+ }
++static int rxrpc_verify_response(struct rxrpc_connection *conn,
++                               struct sk_buff *skb)
++{
++      int ret;
++
++      if (skb_cloned(skb)) {
++              /* Copy the packet if shared so that we can do in-place
++               * decryption.
++               */
++              struct sk_buff *nskb = skb_copy(skb, GFP_NOFS);
++
++              if (nskb) {
++                      rxrpc_new_skb(nskb, rxrpc_skb_new_unshared);
++                      ret = conn->security->verify_response(conn, nskb);
++                      rxrpc_free_skb(nskb, rxrpc_skb_put_response_copy);
++              } else {
++                      /* OOM - Drop the packet. */
++                      rxrpc_see_skb(skb, rxrpc_skb_see_unshare_nomem);
++                      ret = -ENOMEM;
++              }
++      } else {
++              ret = conn->security->verify_response(conn, skb);
++      }
++
++      return ret;
++}
++
+ /*
+  * connection-level Rx packet processor
+  */
+@@ -270,7 +297,7 @@ static int rxrpc_process_event(struct rx
+               }
+               spin_unlock_irq(&conn->state_lock);
+-              ret = conn->security->verify_response(conn, skb);
++              ret = rxrpc_verify_response(conn, skb);
+               if (ret < 0)
+                       return ret;
diff --git a/queue-7.0/rxrpc-fix-error-handling-in-rxgk_extract_token.patch b/queue-7.0/rxrpc-fix-error-handling-in-rxgk_extract_token.patch
new file mode 100644 (file)
index 0000000..d9801b1
--- /dev/null
@@ -0,0 +1,38 @@
+From 3476c8bb960f48e49355d6f93fb7673211e0163f Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Thu, 23 Apr 2026 21:09:08 +0100
+Subject: rxrpc: Fix error handling in rxgk_extract_token()
+
+From: David Howells <dhowells@redhat.com>
+
+commit 3476c8bb960f48e49355d6f93fb7673211e0163f upstream.
+
+Fix a missing bit of error handling in rxgk_extract_token(): in the event
+that rxgk_decrypt_skb() returns -ENOMEM, it should just return that rather
+than continuing on (for anything else, it generates an abort).
+
+Fixes: 64863f4ca494 ("rxrpc: Fix unhandled errors in rxgk_verify_packet_integrity()")
+Closes: https://sashiko.dev/#/patchset/20260422161438.2593376-4-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/20260423200909.3049438-4-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/rxgk_app.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/rxrpc/rxgk_app.c
++++ b/net/rxrpc/rxgk_app.c
+@@ -245,6 +245,7 @@ int rxgk_extract_token(struct rxrpc_conn
+               if (ret != -ENOMEM)
+                       return rxrpc_abort_conn(conn, skb, ec, ret,
+                                               rxgk_abort_resp_tok_dec);
++              return ret;
+       }
+       ret = conn->security->default_decode_ticket(conn, skb, ticket_offset,
diff --git a/queue-7.0/rxrpc-fix-memory-leaks-in-rxkad_verify_response.patch b/queue-7.0/rxrpc-fix-memory-leaks-in-rxkad_verify_response.patch
new file mode 100644 (file)
index 0000000..285a6bd
--- /dev/null
@@ -0,0 +1,231 @@
+From 34f61a07e0cdefaecd3ec03bb5fb22215643678f Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 22 Apr 2026 17:14:30 +0100
+Subject: rxrpc: Fix memory leaks in rxkad_verify_response()
+
+From: David Howells <dhowells@redhat.com>
+
+commit 34f61a07e0cdefaecd3ec03bb5fb22215643678f upstream.
+
+Fix rxkad_verify_response() to free the ticket and the server key under all
+circumstances by initialising the ticket pointer to NULL and then making
+all paths through the function after the first allocation has been done go
+through a single common epilogue that just releases everything - where all
+the releases skip on a NULL pointer.
+
+Fixes: 57af281e5389 ("rxrpc: Tidy up abort generation infrastructure")
+Fixes: ec832bd06d6f ("rxrpc: Don't retain the server key in the connection")
+Closes: https://sashiko.dev/#/patchset/20260408121252.2249051-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/20260422161438.2593376-2-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/rxkad.c |  103 ++++++++++++++++++++++--------------------------------
+ 1 file changed, 42 insertions(+), 61 deletions(-)
+
+--- a/net/rxrpc/rxkad.c
++++ b/net/rxrpc/rxkad.c
+@@ -1136,7 +1136,7 @@ static int rxkad_verify_response(struct
+       struct rxrpc_crypt session_key;
+       struct key *server_key;
+       time64_t expiry;
+-      void *ticket;
++      void *ticket = NULL;
+       u32 version, kvno, ticket_len, level;
+       __be32 csum;
+       int ret, i;
+@@ -1162,13 +1162,13 @@ static int rxkad_verify_response(struct
+       ret = -ENOMEM;
+       response = kzalloc_obj(struct rxkad_response, GFP_NOFS);
+       if (!response)
+-              goto temporary_error;
++              goto error;
+       if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
+                         response, sizeof(*response)) < 0) {
+-              rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO,
+-                               rxkad_abort_resp_short);
+-              goto protocol_error;
++              ret = rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO,
++                                     rxkad_abort_resp_short);
++              goto error;
+       }
+       version = ntohl(response->version);
+@@ -1178,62 +1178,62 @@ static int rxkad_verify_response(struct
+       trace_rxrpc_rx_response(conn, sp->hdr.serial, version, kvno, ticket_len);
+       if (version != RXKAD_VERSION) {
+-              rxrpc_abort_conn(conn, skb, RXKADINCONSISTENCY, -EPROTO,
+-                               rxkad_abort_resp_version);
+-              goto protocol_error;
++              ret = rxrpc_abort_conn(conn, skb, RXKADINCONSISTENCY, -EPROTO,
++                                     rxkad_abort_resp_version);
++              goto error;
+       }
+       if (ticket_len < 4 || ticket_len > MAXKRB5TICKETLEN) {
+-              rxrpc_abort_conn(conn, skb, RXKADTICKETLEN, -EPROTO,
+-                               rxkad_abort_resp_tkt_len);
+-              goto protocol_error;
++              ret = rxrpc_abort_conn(conn, skb, RXKADTICKETLEN, -EPROTO,
++                                     rxkad_abort_resp_tkt_len);
++              goto error;
+       }
+       if (kvno >= RXKAD_TKT_TYPE_KERBEROS_V5) {
+-              rxrpc_abort_conn(conn, skb, RXKADUNKNOWNKEY, -EPROTO,
+-                               rxkad_abort_resp_unknown_tkt);
+-              goto protocol_error;
++              ret = rxrpc_abort_conn(conn, skb, RXKADUNKNOWNKEY, -EPROTO,
++                                     rxkad_abort_resp_unknown_tkt);
++              goto error;
+       }
+       /* extract the kerberos ticket and decrypt and decode it */
+       ret = -ENOMEM;
+       ticket = kmalloc(ticket_len, GFP_NOFS);
+       if (!ticket)
+-              goto temporary_error_free_resp;
++              goto error;
+       if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header) + sizeof(*response),
+                         ticket, ticket_len) < 0) {
+-              rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO,
+-                               rxkad_abort_resp_short_tkt);
+-              goto protocol_error;
++              ret = rxrpc_abort_conn(conn, skb, RXKADPACKETSHORT, -EPROTO,
++                                     rxkad_abort_resp_short_tkt);
++              goto error;
+       }
+       ret = rxkad_decrypt_ticket(conn, server_key, skb, ticket, ticket_len,
+                                  &session_key, &expiry);
+       if (ret < 0)
+-              goto temporary_error_free_ticket;
++              goto error;
+       /* use the session key from inside the ticket to decrypt the
+        * response */
+       ret = rxkad_decrypt_response(conn, response, &session_key);
+       if (ret < 0)
+-              goto temporary_error_free_ticket;
++              goto error;
+       if (ntohl(response->encrypted.epoch) != conn->proto.epoch ||
+           ntohl(response->encrypted.cid) != conn->proto.cid ||
+           ntohl(response->encrypted.securityIndex) != conn->security_ix) {
+-              rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
+-                               rxkad_abort_resp_bad_param);
+-              goto protocol_error_free;
++              ret = rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
++                                     rxkad_abort_resp_bad_param);
++              goto error;
+       }
+       csum = response->encrypted.checksum;
+       response->encrypted.checksum = 0;
+       rxkad_calc_response_checksum(response);
+       if (response->encrypted.checksum != csum) {
+-              rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
+-                               rxkad_abort_resp_bad_checksum);
+-              goto protocol_error_free;
++              ret = rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
++                                     rxkad_abort_resp_bad_checksum);
++              goto error;
+       }
+       for (i = 0; i < RXRPC_MAXCALLS; i++) {
+@@ -1241,38 +1241,38 @@ static int rxkad_verify_response(struct
+               u32 counter = READ_ONCE(conn->channels[i].call_counter);
+               if (call_id > INT_MAX) {
+-                      rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
+-                                       rxkad_abort_resp_bad_callid);
+-                      goto protocol_error_free;
++                      ret = rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
++                                             rxkad_abort_resp_bad_callid);
++                      goto error;
+               }
+               if (call_id < counter) {
+-                      rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
+-                                       rxkad_abort_resp_call_ctr);
+-                      goto protocol_error_free;
++                      ret = rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
++                                             rxkad_abort_resp_call_ctr);
++                      goto error;
+               }
+               if (call_id > counter) {
+                       if (conn->channels[i].call) {
+-                              rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
++                              ret = rxrpc_abort_conn(conn, skb, RXKADSEALEDINCON, -EPROTO,
+                                                rxkad_abort_resp_call_state);
+-                              goto protocol_error_free;
++                              goto error;
+                       }
+                       conn->channels[i].call_counter = call_id;
+               }
+       }
+       if (ntohl(response->encrypted.inc_nonce) != conn->rxkad.nonce + 1) {
+-              rxrpc_abort_conn(conn, skb, RXKADOUTOFSEQUENCE, -EPROTO,
+-                               rxkad_abort_resp_ooseq);
+-              goto protocol_error_free;
++              ret = rxrpc_abort_conn(conn, skb, RXKADOUTOFSEQUENCE, -EPROTO,
++                                     rxkad_abort_resp_ooseq);
++              goto error;
+       }
+       level = ntohl(response->encrypted.level);
+       if (level > RXRPC_SECURITY_ENCRYPT) {
+-              rxrpc_abort_conn(conn, skb, RXKADLEVELFAIL, -EPROTO,
+-                               rxkad_abort_resp_level);
+-              goto protocol_error_free;
++              ret = rxrpc_abort_conn(conn, skb, RXKADLEVELFAIL, -EPROTO,
++                                     rxkad_abort_resp_level);
++              goto error;
+       }
+       conn->security_level = level;
+@@ -1280,31 +1280,12 @@ static int rxkad_verify_response(struct
+        * this the connection security can be handled in exactly the same way
+        * as for a client connection */
+       ret = rxrpc_get_server_data_key(conn, &session_key, expiry, kvno);
+-      if (ret < 0)
+-              goto temporary_error_free_ticket;
+-
+-      kfree(ticket);
+-      kfree(response);
+-      _leave(" = 0");
+-      return 0;
+-
+-protocol_error_free:
+-      kfree(ticket);
+-protocol_error:
+-      kfree(response);
+-      key_put(server_key);
+-      return -EPROTO;
+-temporary_error_free_ticket:
++error:
+       kfree(ticket);
+-temporary_error_free_resp:
+       kfree(response);
+-temporary_error:
+-      /* Ignore the response packet if we got a temporary error such as
+-       * ENOMEM.  We just want to send the challenge again.  Note that we
+-       * also come out this way if the ticket decryption fails.
+-       */
+       key_put(server_key);
++      _leave(" = %d", ret);
+       return ret;
+ }
diff --git a/queue-7.0/rxrpc-fix-potential-uaf-after-skb_unshare-failure.patch b/queue-7.0/rxrpc-fix-potential-uaf-after-skb_unshare-failure.patch
new file mode 100644 (file)
index 0000000..32e3ea4
--- /dev/null
@@ -0,0 +1,176 @@
+From 1f2740150f904bfa60e4bad74d65add3ccb5e7f8 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 22 Apr 2026 17:14:32 +0100
+Subject: rxrpc: Fix potential UAF after skb_unshare() failure
+
+From: David Howells <dhowells@redhat.com>
+
+commit 1f2740150f904bfa60e4bad74d65add3ccb5e7f8 upstream.
+
+If skb_unshare() fails to unshare a packet due to allocation failure in
+rxrpc_input_packet(), the skb pointer in the parent (rxrpc_io_thread())
+will be NULL'd out.  This will likely cause the call to
+trace_rxrpc_rx_done() to oops.
+
+Fix this by moving the unsharing down to where rxrpc_input_call_event()
+calls rxrpc_input_call_packet().  There are a number of places prior to
+that where we ignore DATA packets for a variety of reasons (such as the
+call already being complete) for which an unshare is then avoided.
+
+And with that, rxrpc_input_packet() doesn't need to take a pointer to the
+pointer to the packet, so change that to just a pointer.
+
+Fixes: 2d1faf7a0ca3 ("rxrpc: Simplify skbuff accounting in receive path")
+Closes: https://sashiko.dev/#/patchset/20260408121252.2249051-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/20260422161438.2593376-4-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 |    4 ++--
+ net/rxrpc/ar-internal.h      |    1 -
+ net/rxrpc/call_event.c       |   19 ++++++++++++++++++-
+ net/rxrpc/io_thread.c        |   24 ++----------------------
+ net/rxrpc/skbuff.c           |    9 ---------
+ 5 files changed, 22 insertions(+), 35 deletions(-)
+
+--- a/include/trace/events/rxrpc.h
++++ b/include/trace/events/rxrpc.h
+@@ -161,8 +161,6 @@
+       E_(rxrpc_call_poke_timer_now,           "Timer-now")
+ #define rxrpc_skb_traces \
+-      EM(rxrpc_skb_eaten_by_unshare,          "ETN unshare  ") \
+-      EM(rxrpc_skb_eaten_by_unshare_nomem,    "ETN unshar-nm") \
+       EM(rxrpc_skb_get_call_rx,               "GET call-rx  ") \
+       EM(rxrpc_skb_get_conn_secured,          "GET conn-secd") \
+       EM(rxrpc_skb_get_conn_work,             "GET conn-work") \
+@@ -189,6 +187,7 @@
+       EM(rxrpc_skb_put_purge,                 "PUT purge    ") \
+       EM(rxrpc_skb_put_purge_oob,             "PUT purge-oob") \
+       EM(rxrpc_skb_put_response,              "PUT response ") \
++      EM(rxrpc_skb_put_response_copy,         "PUT resp-cpy ") \
+       EM(rxrpc_skb_put_rotate,                "PUT rotate   ") \
+       EM(rxrpc_skb_put_unknown,               "PUT unknown  ") \
+       EM(rxrpc_skb_see_conn_work,             "SEE conn-work") \
+@@ -197,6 +196,7 @@
+       EM(rxrpc_skb_see_recvmsg_oob,           "SEE recvm-oob") \
+       EM(rxrpc_skb_see_reject,                "SEE reject   ") \
+       EM(rxrpc_skb_see_rotate,                "SEE rotate   ") \
++      EM(rxrpc_skb_see_unshare_nomem,         "SEE unshar-nm") \
+       E_(rxrpc_skb_see_version,               "SEE version  ")
+ #define rxrpc_local_traces \
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -1486,7 +1486,6 @@ int rxrpc_server_keyring(struct rxrpc_so
+ void rxrpc_kernel_data_consumed(struct rxrpc_call *, struct sk_buff *);
+ void rxrpc_new_skb(struct sk_buff *, enum rxrpc_skb_trace);
+ void rxrpc_see_skb(struct sk_buff *, enum rxrpc_skb_trace);
+-void rxrpc_eaten_skb(struct sk_buff *, enum rxrpc_skb_trace);
+ void rxrpc_get_skb(struct sk_buff *, enum rxrpc_skb_trace);
+ void rxrpc_free_skb(struct sk_buff *, enum rxrpc_skb_trace);
+ void rxrpc_purge_queue(struct sk_buff_head *);
+--- a/net/rxrpc/call_event.c
++++ b/net/rxrpc/call_event.c
+@@ -332,7 +332,24 @@ bool rxrpc_input_call_event(struct rxrpc
+                       saw_ack |= sp->hdr.type == RXRPC_PACKET_TYPE_ACK;
+-                      rxrpc_input_call_packet(call, skb);
++                      if (sp->hdr.securityIndex != 0 &&
++                          skb_cloned(skb)) {
++                              /* Unshare the packet so that it can be
++                               * modified by in-place decryption.
++                               */
++                              struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
++
++                              if (nskb) {
++                                      rxrpc_new_skb(nskb, rxrpc_skb_new_unshared);
++                                      rxrpc_input_call_packet(call, nskb);
++                                      rxrpc_free_skb(nskb, rxrpc_skb_put_call_rx);
++                              } else {
++                                      /* OOM - Drop the packet. */
++                                      rxrpc_see_skb(skb, rxrpc_skb_see_unshare_nomem);
++                              }
++                      } else {
++                              rxrpc_input_call_packet(call, skb);
++                      }
+                       rxrpc_free_skb(skb, rxrpc_skb_put_call_rx);
+                       did_receive = true;
+               }
+--- a/net/rxrpc/io_thread.c
++++ b/net/rxrpc/io_thread.c
+@@ -192,13 +192,12 @@ static bool rxrpc_extract_abort(struct s
+ /*
+  * Process packets received on the local endpoint
+  */
+-static bool rxrpc_input_packet(struct rxrpc_local *local, struct sk_buff **_skb)
++static bool rxrpc_input_packet(struct rxrpc_local *local, struct sk_buff *skb)
+ {
+       struct rxrpc_connection *conn;
+       struct sockaddr_rxrpc peer_srx;
+       struct rxrpc_skb_priv *sp;
+       struct rxrpc_peer *peer = NULL;
+-      struct sk_buff *skb = *_skb;
+       bool ret = false;
+       skb_pull(skb, sizeof(struct udphdr));
+@@ -244,25 +243,6 @@ static bool rxrpc_input_packet(struct rx
+                       return rxrpc_bad_message(skb, rxrpc_badmsg_zero_call);
+               if (sp->hdr.seq == 0)
+                       return rxrpc_bad_message(skb, rxrpc_badmsg_zero_seq);
+-
+-              /* Unshare the packet so that it can be modified for in-place
+-               * decryption.
+-               */
+-              if (sp->hdr.securityIndex != 0) {
+-                      skb = skb_unshare(skb, GFP_ATOMIC);
+-                      if (!skb) {
+-                              rxrpc_eaten_skb(*_skb, rxrpc_skb_eaten_by_unshare_nomem);
+-                              *_skb = NULL;
+-                              return just_discard;
+-                      }
+-
+-                      if (skb != *_skb) {
+-                              rxrpc_eaten_skb(*_skb, rxrpc_skb_eaten_by_unshare);
+-                              *_skb = skb;
+-                              rxrpc_new_skb(skb, rxrpc_skb_new_unshared);
+-                              sp = rxrpc_skb(skb);
+-                      }
+-              }
+               break;
+       case RXRPC_PACKET_TYPE_CHALLENGE:
+@@ -494,7 +474,7 @@ int rxrpc_io_thread(void *data)
+                       switch (skb->mark) {
+                       case RXRPC_SKB_MARK_PACKET:
+                               skb->priority = 0;
+-                              if (!rxrpc_input_packet(local, &skb))
++                              if (!rxrpc_input_packet(local, skb))
+                                       rxrpc_reject_packet(local, skb);
+                               trace_rxrpc_rx_done(skb->mark, skb->priority);
+                               rxrpc_free_skb(skb, rxrpc_skb_put_input);
+--- a/net/rxrpc/skbuff.c
++++ b/net/rxrpc/skbuff.c
+@@ -47,15 +47,6 @@ void rxrpc_get_skb(struct sk_buff *skb,
+ }
+ /*
+- * Note the dropping of a ref on a socket buffer by the core.
+- */
+-void rxrpc_eaten_skb(struct sk_buff *skb, enum rxrpc_skb_trace why)
+-{
+-      int n = atomic_inc_return(&rxrpc_n_rx_skbs);
+-      trace_rxrpc_skb(skb, 0, n, why);
+-}
+-
+-/*
+  * Note the destruction of a socket buffer.
+  */
+ void rxrpc_free_skb(struct sk_buff *skb, enum rxrpc_skb_trace why)
diff --git a/queue-7.0/rxrpc-fix-re-decryption-of-response-packets.patch b/queue-7.0/rxrpc-fix-re-decryption-of-response-packets.patch
new file mode 100644 (file)
index 0000000..7be5d29
--- /dev/null
@@ -0,0 +1,73 @@
+From 0422e7a4883f25101903f3e8105c0808aa5f4ce9 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Thu, 23 Apr 2026 21:09:07 +0100
+Subject: rxrpc: Fix re-decryption of RESPONSE packets
+
+From: David Howells <dhowells@redhat.com>
+
+commit 0422e7a4883f25101903f3e8105c0808aa5f4ce9 upstream.
+
+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.
+
+Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
+Closes: https://sashiko.dev/#/patchset/20260422161438.2593376-4-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/20260423200909.3049438-3-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 |    1 -
+ net/rxrpc/conn_event.c       |   14 ++------------
+ 2 files changed, 2 insertions(+), 13 deletions(-)
+
+--- 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") \
+--- 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(
+        * 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);
+       }
+ }
diff --git a/queue-7.0/rxrpc-fix-rxkad-crypto-unalignment-handling.patch b/queue-7.0/rxrpc-fix-rxkad-crypto-unalignment-handling.patch
new file mode 100644 (file)
index 0000000..b1f1ec8
--- /dev/null
@@ -0,0 +1,65 @@
+From def304aae2edf321d2671fd6ca766a93c21f877e Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 22 Apr 2026 17:14:31 +0100
+Subject: rxrpc: Fix rxkad crypto unalignment handling
+
+From: David Howells <dhowells@redhat.com>
+
+commit def304aae2edf321d2671fd6ca766a93c21f877e upstream.
+
+Fix handling of a packet with a misaligned crypto length.  Also handle
+non-ENOMEM errors from decryption by aborting.  Further, remove the
+WARN_ON_ONCE() so that it can't be remotely triggered (a trace line can
+still be emitted).
+
+Fixes: f93af41b9f5f ("rxrpc: Fix missing error checks for rxkad encryption/decryption failure")
+Closes: https://sashiko.dev/#/patchset/20260408121252.2249051-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/20260422161438.2593376-3-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 |    1 +
+ net/rxrpc/rxkad.c            |    9 +++++++--
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/include/trace/events/rxrpc.h
++++ b/include/trace/events/rxrpc.h
+@@ -37,6 +37,7 @@
+       EM(rxkad_abort_1_short_encdata,         "rxkad1-short-encdata") \
+       EM(rxkad_abort_1_short_header,          "rxkad1-short-hdr")     \
+       EM(rxkad_abort_2_short_check,           "rxkad2-short-check")   \
++      EM(rxkad_abort_2_crypto_unaligned,      "rxkad2-crypto-unaligned") \
+       EM(rxkad_abort_2_short_data,            "rxkad2-short-data")    \
+       EM(rxkad_abort_2_short_header,          "rxkad2-short-hdr")     \
+       EM(rxkad_abort_2_short_len,             "rxkad2-short-len")     \
+--- a/net/rxrpc/rxkad.c
++++ b/net/rxrpc/rxkad.c
+@@ -510,6 +510,9 @@ static int rxkad_verify_packet_2(struct
+               return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
+                                         rxkad_abort_2_short_header);
++      /* Don't let the crypto algo see a misaligned length. */
++      sp->len = round_down(sp->len, 8);
++
+       /* Decrypt the skbuff in-place.  TODO: We really want to decrypt
+        * directly into the target buffer.
+        */
+@@ -543,8 +546,10 @@ static int rxkad_verify_packet_2(struct
+       if (sg != _sg)
+               kfree(sg);
+       if (ret < 0) {
+-              WARN_ON_ONCE(ret != -ENOMEM);
+-              return ret;
++              if (ret == -ENOMEM)
++                      return ret;
++              return rxrpc_abort_eproto(call, skb, RXKADSEALEDINCON,
++                                        rxkad_abort_2_crypto_unaligned);
+       }
+       /* Extract the decrypted packet length */
diff --git a/queue-7.0/rxrpc-fix-rxrpc_input_call_event-to-only-unshare-data-packets.patch b/queue-7.0/rxrpc-fix-rxrpc_input_call_event-to-only-unshare-data-packets.patch
new file mode 100644 (file)
index 0000000..899276e
--- /dev/null
@@ -0,0 +1,42 @@
+From 55b2984c96c37f909bbfe8851f13152693951382 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Thu, 23 Apr 2026 21:09:06 +0100
+Subject: rxrpc: Fix rxrpc_input_call_event() to only unshare DATA packets
+
+From: David Howells <dhowells@redhat.com>
+
+commit 55b2984c96c37f909bbfe8851f13152693951382 upstream.
+
+Fix rxrpc_input_call_event() to only unshare DATA packets and not ACK,
+ABORT, etc..
+
+And with that, rxrpc_input_packet() doesn't need to take a pointer to the
+pointer to the packet, so change that to just a pointer.
+
+Fixes: 1f2740150f90 ("rxrpc: Fix potential UAF after skb_unshare() failure")
+Closes: https://sashiko.dev/#/patchset/20260422161438.2593376-4-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/20260423200909.3049438-2-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/call_event.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/rxrpc/call_event.c
++++ b/net/rxrpc/call_event.c
+@@ -332,7 +332,8 @@ bool rxrpc_input_call_event(struct rxrpc
+                       saw_ack |= sp->hdr.type == RXRPC_PACKET_TYPE_ACK;
+-                      if (sp->hdr.securityIndex != 0 &&
++                      if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA &&
++                          sp->hdr.securityIndex != 0 &&
+                           skb_cloned(skb)) {
+                               /* Unshare the packet so that it can be
+                                * modified by in-place decryption.
index 38a88ea66821709edcd876947771cfe2054392e1..920faec8f0eea00d99a243fcfc48c6edfd6e64b3 100644 (file)
@@ -123,3 +123,13 @@ alsa-pcmtest-fix-reference-leak-on-failed-device-registration.patch
 alsa-pcmtest-fix-resource-leaks-in-module-init-error-paths.patch
 iio-adc-ad7768-1-fix-one-shot-mode-data-acquisition.patch
 iio-adc-ad7768-1-remove-switch-to-one-shot-mode.patch
+rxrpc-fix-potential-uaf-after-skb_unshare-failure.patch
+rxrpc-fix-memory-leaks-in-rxkad_verify_response.patch
+rxrpc-fix-conn-level-packet-handling-to-unshare-response-packets.patch
+rxrpc-fix-rxkad-crypto-unalignment-handling.patch
+rxrpc-fix-error-handling-in-rxgk_extract_token.patch
+rxrpc-fix-re-decryption-of-response-packets.patch
+rxrpc-fix-rxrpc_input_call_event-to-only-unshare-data-packets.patch
+edac-versalnet-fix-memory-leak-in-remove-and-probe-error-paths.patch
+tools-accounting-handle-truncated-taskstats-netlink-messages.patch
+net-txgbe-fix-rtnl-assertion-warning-when-remove-module.patch
diff --git a/queue-7.0/tools-accounting-handle-truncated-taskstats-netlink-messages.patch b/queue-7.0/tools-accounting-handle-truncated-taskstats-netlink-messages.patch
new file mode 100644 (file)
index 0000000..1689bea
--- /dev/null
@@ -0,0 +1,181 @@
+From cc82b3dcc6a8fa259fbda12ab00d6fc00908a49e Mon Sep 17 00:00:00 2001
+From: Yiyang Chen <cyyzero16@gmail.com>
+Date: Mon, 30 Mar 2026 03:00:41 +0800
+Subject: tools/accounting: handle truncated taskstats netlink messages
+
+From: Yiyang Chen <cyyzero16@gmail.com>
+
+commit cc82b3dcc6a8fa259fbda12ab00d6fc00908a49e upstream.
+
+procacct and getdelays use a fixed receive buffer for taskstats generic
+netlink messages.  A multi-threaded process exit can emit a single
+PID+TGID notification large enough to exceed that buffer on newer kernels.
+
+Switch to recvmsg() so MSG_TRUNC is detected explicitly, increase the
+message buffer size, and report truncated datagrams clearly instead of
+misparsing them as fatal netlink errors.
+
+Also print the taskstats version in debug output to make version
+mismatches easier to diagnose while inspecting taskstats traffic.
+
+Link: https://lkml.kernel.org/r/520308bb4cbbaf8dc2c7296b5f60f11e12fb30a5.1774810498.git.cyyzero16@gmail.com
+Signed-off-by: Yiyang Chen <cyyzero16@gmail.com>
+Cc: Balbir Singh <bsingharora@gmail.com>
+Cc: Dr. Thomas Orgis <thomas.orgis@uni-hamburg.de>
+Cc: Fan Yu <fan.yu9@zte.com.cn>
+Cc: Wang Yaxin <wang.yaxin@zte.com.cn>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/accounting/getdelays.c |   41 +++++++++++++++++++++++++++++++++++++----
+ tools/accounting/procacct.c  |   40 ++++++++++++++++++++++++++++++++++++----
+ 2 files changed, 73 insertions(+), 8 deletions(-)
+
+--- a/tools/accounting/getdelays.c
++++ b/tools/accounting/getdelays.c
+@@ -60,7 +60,7 @@ int print_task_context_switch_counts;
+       }
+ /* Maximum size of response requested or message sent */
+-#define MAX_MSG_SIZE  1024
++#define MAX_MSG_SIZE  2048
+ /* Maximum number of cpus expected to be specified in a cpumask */
+ #define MAX_CPUS      32
+@@ -115,6 +115,32 @@ error:
+       return -1;
+ }
++static int recv_taskstats_msg(int sd, struct msgtemplate *msg)
++{
++      struct sockaddr_nl nladdr;
++      struct iovec iov = {
++              .iov_base = msg,
++              .iov_len = sizeof(*msg),
++      };
++      struct msghdr hdr = {
++              .msg_name = &nladdr,
++              .msg_namelen = sizeof(nladdr),
++              .msg_iov = &iov,
++              .msg_iovlen = 1,
++      };
++      int ret;
++
++      ret = recvmsg(sd, &hdr, 0);
++      if (ret < 0)
++              return -1;
++      if (hdr.msg_flags & MSG_TRUNC) {
++              errno = EMSGSIZE;
++              return -1;
++      }
++
++      return ret;
++}
++
+ static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
+            __u8 genl_cmd, __u16 nla_type,
+@@ -633,12 +659,16 @@ int main(int argc, char *argv[])
+       }
+       do {
+-              rep_len = recv(nl_sd, &msg, sizeof(msg), 0);
++              rep_len = recv_taskstats_msg(nl_sd, &msg);
+               PRINTF("received %d bytes\n", rep_len);
+               if (rep_len < 0) {
+-                      fprintf(stderr, "nonfatal reply error: errno %d\n",
+-                              errno);
++                      if (errno == EMSGSIZE)
++                              fprintf(stderr,
++                                      "dropped truncated taskstats netlink message, please increase MAX_MSG_SIZE\n");
++                      else
++                              fprintf(stderr, "nonfatal reply error: errno %d\n",
++                                      errno);
+                       continue;
+               }
+               if (msg.n.nlmsg_type == NLMSG_ERROR ||
+@@ -680,6 +710,9 @@ int main(int argc, char *argv[])
+                                                       printf("TGID\t%d\n", rtid);
+                                               break;
+                                       case TASKSTATS_TYPE_STATS:
++                                              PRINTF("version %u\n",
++                                                     ((struct taskstats *)
++                                                      NLA_DATA(na))->version);
+                                               if (print_delays)
+                                                       print_delayacct((struct taskstats *) NLA_DATA(na));
+                                               if (print_io_accounting)
+--- a/tools/accounting/procacct.c
++++ b/tools/accounting/procacct.c
+@@ -71,7 +71,7 @@ int print_task_context_switch_counts;
+       }
+ /* Maximum size of response requested or message sent */
+-#define MAX_MSG_SIZE  1024
++#define MAX_MSG_SIZE  2048
+ /* Maximum number of cpus expected to be specified in a cpumask */
+ #define MAX_CPUS      32
+@@ -121,6 +121,32 @@ error:
+       return -1;
+ }
++static int recv_taskstats_msg(int sd, struct msgtemplate *msg)
++{
++      struct sockaddr_nl nladdr;
++      struct iovec iov = {
++              .iov_base = msg,
++              .iov_len = sizeof(*msg),
++      };
++      struct msghdr hdr = {
++              .msg_name = &nladdr,
++              .msg_namelen = sizeof(nladdr),
++              .msg_iov = &iov,
++              .msg_iovlen = 1,
++      };
++      int ret;
++
++      ret = recvmsg(sd, &hdr, 0);
++      if (ret < 0)
++              return -1;
++      if (hdr.msg_flags & MSG_TRUNC) {
++              errno = EMSGSIZE;
++              return -1;
++      }
++
++      return ret;
++}
++
+ static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
+            __u8 genl_cmd, __u16 nla_type,
+@@ -239,6 +265,8 @@ void handle_aggr(int mother, struct nlat
+                       PRINTF("TGID\t%d\n", rtid);
+                       break;
+               case TASKSTATS_TYPE_STATS:
++                      PRINTF("version %u\n",
++                             ((struct taskstats *)NLA_DATA(na))->version);
+                       if (mother == TASKSTATS_TYPE_AGGR_PID)
+                               print_procacct((struct taskstats *) NLA_DATA(na));
+                       if (fd) {
+@@ -347,12 +375,16 @@ int main(int argc, char *argv[])
+       }
+       do {
+-              rep_len = recv(nl_sd, &msg, sizeof(msg), 0);
++              rep_len = recv_taskstats_msg(nl_sd, &msg);
+               PRINTF("received %d bytes\n", rep_len);
+               if (rep_len < 0) {
+-                      fprintf(stderr, "nonfatal reply error: errno %d\n",
+-                              errno);
++                      if (errno == EMSGSIZE)
++                              fprintf(stderr,
++                                      "dropped truncated taskstats netlink message, please increase MAX_MSG_SIZE\n");
++                      else
++                              fprintf(stderr, "nonfatal reply error: errno %d\n",
++                                      errno);
+                       continue;
+               }
+               if (msg.n.nlmsg_type == NLMSG_ERROR ||