linux-gbmc: 5.15: fix mctp skb memory leak
Backport upstream commit 64f16b2cfc1b ("mctp: handle skb cleanup on
sock_queue failures") to Linux 5.15 to prevent kernel sk_buff memory leak
when delivering incoming MCTP packets to a socket where sock_queue_rcv_skb
fails (e.g. socket receive buffer is full or socket is shutting down).
Upstream-Status: Backport [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=64f16b2cfc1b017b2b8d4bb98d407ff5661b173c]
Tested:
- Compiled obmc-phosphor-image with 0 patch fuzz and 0 build errors.
- Verified in QEMU simulation with active MCTP interfaces and mctpd service.
- Deployed signed A/B image to physical lab hardware (ddche15-nfd01). Verified:
* uname -r: 5.15.167
* 9 MCTP I2C interfaces (mctpi2c2, mctpi2c4..mctpi2c11) UP/LOWER_UP.
* mctpd service active and running without leak warnings.
* /proc/net/protocols: MCTP protocol family 576 active.
Fusion-Link: http://fusion2/ci/kokoro/prod%3Agbmc%2Ffirmware-build%2Ffirmware%2Fredacted_gbmc_platforms/activity/ace1fcb5-15a8-4f37-9492-9a1a5e96b3a4
Google-Bug-Id: 543881748
Change-Id: I17ce42658400de8af561b773521830f682ae25fd
Signed-off-by: Joseph CT Chan <josephctchan@google.com>
diff --git a/recipes-kernel/linux/5.15/0001-net-mctp-handle-skb-cleanup-on-sock_queue-failures.patch b/recipes-kernel/linux/5.15/0001-net-mctp-handle-skb-cleanup-on-sock_queue-failures.patch
new file mode 100644
index 0000000..8475a5a
--- /dev/null
+++ b/recipes-kernel/linux/5.15/0001-net-mctp-handle-skb-cleanup-on-sock_queue-failures.patch
@@ -0,0 +1,57 @@
+From ce1219c3f76bb131d095e90521506d3c6ccfa086 Mon Sep 17 00:00:00 2001
+From: Jeremy Kerr <jk@codeconstruct.com.au>
+Date: Wed, 18 Dec 2024 16:34:00 +0800
+Subject: [PATCH] net: mctp: handle skb cleanup on sock_queue failures
+
+Upstream-Status: Backport [ce1219c3f76bb131d095e90521506d3c6ccfa086]
+
+In mctp_route_input(), if sock_queue_rcv_skb() fails (e.g. when socket
+receive buffer is exhausted), the skb is not freed, leaking socket
+buffer memory.
+
+Ensure that the return code of sock_queue_rcv_skb() is captured, that
+skb ownership is cleared only on success (leaving unowned skbs to be
+freed by kfree_skb()), and that reasm_head is not cleared on failure so
+__mctp_key_done_in() can release the fragment list.
+
+Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
+---
+ net/mctp/route.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/net/mctp/route.c b/net/mctp/route.c
+index 404a06690fa5..350b693ebeba 100644
+--- a/net/mctp/route.c
++++ b/net/mctp/route.c
+@@ -397,7 +397,9 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
+ * pending key.
+ */
+ if (flags & MCTP_HDR_FLAG_EOM) {
+- sock_queue_rcv_skb(&msk->sk, skb);
++ rc = sock_queue_rcv_skb(&msk->sk, skb);
++ if (!rc)
++ skb = NULL;
+ if (key) {
+ /* we've hit a pending reassembly; not much we
+ * can do but drop it
+@@ -406,7 +408,6 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
+ MCTP_TRACE_KEY_REPLIED);
+ key = NULL;
+ }
+- rc = 0;
+ goto out_unlock;
+ }
+
+@@ -470,8 +471,9 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
+ * the reassembly/response key
+ */
+ if (!rc && flags & MCTP_HDR_FLAG_EOM) {
+- sock_queue_rcv_skb(key->sk, key->reasm_head);
+- key->reasm_head = NULL;
++ rc = sock_queue_rcv_skb(key->sk, key->reasm_head);
++ if (!rc)
++ key->reasm_head = NULL;
+ __mctp_key_done_in(key, net, f, MCTP_TRACE_KEY_REPLIED);
+ key = NULL;
+ }
+--
diff --git a/recipes-kernel/linux/linux-gbmc_5.15.bb b/recipes-kernel/linux/linux-gbmc_5.15.bb
index 4952fe3..20552f7 100644
--- a/recipes-kernel/linux/linux-gbmc_5.15.bb
+++ b/recipes-kernel/linux/linux-gbmc_5.15.bb
@@ -36,6 +36,7 @@
file://0001-Add-STEF48H28-driver.patch \
file://0001-hwmon-pmbus-tps53679-Add-linear-mode-support.patch \
file://0002-hwmon-pmbus-tps53679-Add-TPS53685-and-TPS53686-support.patch \
+ file://0001-net-mctp-handle-skb-cleanup-on-sock_queue-failures.patch \
"
SRC_URI:append:aspeed-g6 = " \