From nobody Sat Sep 26 08:37:37 2026 Received: from codeconstruct.com.au (pi.codeconstruct.com.au [203.29.241.158]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A0D391A2C04; Thu, 3 Sep 2026 02:42:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.29.241.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403370; cv=none; b=BUQS8nE9KXhAsvwKLCrMCJxwZ/XbQq984+VZjMsYqqdaVrtFo6wcK5d5R9IRpLH7HL0y83fbOLyimApmrar7NbAjfpxbqujzBoYGj4JYNemaY/SveoNfMi62CpLd6NgueZYe6Xba0UldGK5v0a1/bPCr65xvabtUpABwseunzKs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403370; c=relaxed/simple; bh=T2zwEOSKeJVPvjSKm2GKFRJuXwoncrPadWyEQ19not8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Garjkb+4+aVSlunRsiLZ/r/1G3c1Q7AZIAuMtZX1uCLTCVfPNJqF2JP70w2cm9mq4s0Ftvgc8KMF8132RrLRr3305SlsrqypbFxF9VPFXSgNdzr+4RVwSWVzmaMRu8VMSuIxoKWQlBySl4w83qhLB3EMVNjvcSm00reWICAxJr8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au; spf=pass smtp.mailfrom=codeconstruct.com.au; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b=DovHcs0u; arc=none smtp.client-ip=203.29.241.158 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b="DovHcs0u" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788403359; bh=PbFhoF6jYTVQDww2xy+ijFIf+3flRX07CkM/MkYCtcE=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=DovHcs0uGp7medxvpAst+3uw8UZSYEu/lX/baVyX1zYPM5lFhZgu6xnTiIeCDu983 0xILcmxk/t0P7jGZ3YEG/ZvxMWSVph+Q5/bXJuELh5xUrYPhwMso1WF+duHwYVaSON D25miYWRc1JOdIMWHz6F1eATLjgnonLt4iVjgwyD/UJcIEcmKokd4QEdhOjdODti6M A0M50xATw+ky2sq8NvxUg/jj5YNRhmktaZL4LbFS7GaQ14kmsBOGzV4wj16RH0YBh6 +V1vrqmrl4goxIbh814p7hA+aSAKM24szxPp15mRJOfFPyIkgVBS7ocSXqJXzW2s4c K88cRcA7CdwgA== Received: by codeconstruct.com.au (Postfix, from userid 10004) id 095E068690; Thu, 3 Sep 2026 10:42:39 +0800 (AWST) From: James Lee Date: Thu, 03 Sep 2026 10:42:18 +0800 Subject: [PATCH net-next v2 1/7] net: mctp: usblib: Add to parameterized kunit tests. Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260903-dev-mctp-usb-lib-test-v2-1-313cf15e0b56@codeconstruct.com.au> References: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> In-Reply-To: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> To: Jeremy Kerr , Matt Johnston , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Kees Cook , "Gustavo A. R. Silva" Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, James Lee X-Mailer: b4 0.14.2 Add parameterized tests to cover worst case scenarios for packet splitting and length. Signed-off-by: James Lee --- drivers/net/mctp/mctp-usblib-test.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/mctp/mctp-usblib-test.c b/drivers/net/mctp/mctp-us= blib-test.c index 9df401a914ff537207911f03bd08f32b5a5e20d1..4c27307900fb6116572bc9d89f3= def6f06c30397 100644 --- a/drivers/net/mctp/mctp-usblib-test.c +++ b/drivers/net/mctp/mctp-usblib-test.c @@ -386,12 +386,18 @@ static const struct mctp_usblib_test_pkt_span mctp_us= blib_test_pkt_spans[] =3D { { "1p2x-split-mctphdr", 1, { 16 }, 2, { 6, 10 } }, /* Single packet split over 3 transfers, middle entirely continuation */ { "1p3x-split", 1, { 12 }, 3, { 4, 4, 4 } }, + /* A packet split over 5 transfers, splitting on and between each header.= */ + { "1p5x-split", 1, { 12 }, 5, { 3, 1, 1, 3, 4}}, /* Max-sized single transfer */ { "1p1x-large", 1, { 8191 }, 1, { 8191 } }, /* Two large packets, split at the worst-case for allocation, with a * single byte continuing the span */ - { "2p2x-large-split", 2, { 8190, 8190 }, 2, { 8191, 8189 } }, + { "2p2x-large-split", 2, { 8190, 8191 }, 2, { 8191, 8190 } }, + /* Three large packets, split at the worst-case for allocation, + * with a single byte continuing each span + */ + { "3p3x-large-split", 3, { 8190, 8191, 8191 }, 3, { 8191, 8191, 8190 } }, }; =20 KUNIT_ARRAY_PARAM(mctp_usblib_test_rx_pkt_span, mctp_usblib_test_pkt_spans, --=20 2.47.3 From nobody Sat Sep 26 08:37:37 2026 Received: from codeconstruct.com.au (pi.codeconstruct.com.au [203.29.241.158]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35C93349CCD; Thu, 3 Sep 2026 02:42:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.29.241.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403371; cv=none; b=qNMT+cEzdOolye6upSeulQQfzan3EfAak6zs1VtL2Ksm8HtTbQnQIOX97R21T+PkV2vxjGBKzdkpwEdoVMfAOLwl0QkpMh9by4sUwrO6CYTgU9piWeoaAUFUKw+Q3v8IIqhIXIlJGHBkqo+wY98eee3RSlufkq3ct9C9aZyx4Go= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403371; c=relaxed/simple; bh=mMvO4b4n2Sf1QhTLIEzIQcY20H6QvmMIqWQIF35BWlk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TOdGv3f4bXRc+CzFsb1ksUU7q+cXlu8XF+mYLk8khYeESbUVSjBp2uOe4yfFb74WJ+Am+WtuMnU9G/c1pNWWOrWC4mpsCBalBWPjMs+fKfQGwJOC52q5KjAu0TpPVBvzDK2scWKSm+QT1NML7OJZlWl9qMamsNF8RttQsAjg5no= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au; spf=pass smtp.mailfrom=codeconstruct.com.au; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b=VsXvQyPb; arc=none smtp.client-ip=203.29.241.158 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b="VsXvQyPb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788403359; bh=8+t3CYaVZfeSpwgWXkwVWrWI6AdFZrilGRE2KDHZsmg=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=VsXvQyPbC83Tleiy6KCEMLBsbtm00aSMTrUNC44yTIGDSyNNwDU6u0vQlUWjd/QeU VigmYs/LUoH0uypbjwpIM24x6pJT6o2Be8gVnHD9qSpJcR0KFqr9mu6QH0y8e5KB84 A8La0AchLtuEvpyQBcJh/ipuCW7Oyrw/0kdDGhpt3M9WGy6ManoMYg0ZSrQ4hQJNBT +r1df6HA1iX13dfYUeeoW1zxQ2uWiewW8uNwMbdvXL7fiBSH/uNC7HHURw/FcRMXCL 1lXIZMpnfOVDykxDQy86dCuPkxdkwchytkhSyf335tjX8vUZ2w9SFGRZN2I0QpQel6 M5Wua1T+DGyVQ== Received: by codeconstruct.com.au (Postfix, from userid 10004) id 65CC568692; Thu, 3 Sep 2026 10:42:39 +0800 (AWST) From: James Lee Date: Thu, 03 Sep 2026 10:42:19 +0800 Subject: [PATCH net-next v2 2/7] net: mctp: usblib: Add test for splits inside headers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260903-dev-mctp-usb-lib-test-v2-2-313cf15e0b56@codeconstruct.com.au> References: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> In-Reply-To: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> To: Jeremy Kerr , Matt Johnston , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Kees Cook , "Gustavo A. R. Silva" Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, James Lee X-Mailer: b4 0.14.2 Add test covering every possible split of a packet's headers between transfers and remove parameterized tests that are now covered. Signed-off-by: James Lee --- v2: - Replace direct calls to mctp_usblib_rx_complete() - Fix sk_buff leak --- drivers/net/mctp/mctp-usblib-test.c | 71 +++++++++++++++++++++++++++++++++= ---- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/drivers/net/mctp/mctp-usblib-test.c b/drivers/net/mctp/mctp-us= blib-test.c index 4c27307900fb6116572bc9d89f3def6f06c30397..a2ca79f61910af129af956a6f38= ad69d5dae8c10 100644 --- a/drivers/net/mctp/mctp-usblib-test.c +++ b/drivers/net/mctp/mctp-usblib-test.c @@ -14,6 +14,8 @@ #include #include =20 +#define HDR_LEN sizeof(struct mctp_usb_hdr) + struct mctp_usblib_test_dev { struct net_device *ndev; struct mctp_dev *mdev; @@ -378,12 +380,6 @@ static const struct mctp_usblib_test_pkt_span mctp_usb= lib_test_pkt_spans[] =3D { { "1p1x-complete", 1, { 8 }, 1, { 8 } }, /* Two small packets combined within one transfer */ { "2p1x-combined", 2, { 8, 8 }, 1, { 16 } }, - /* A packet split over two transfers, at the MCTP payload */ - { "1p2x-split-payload", 1, { 16 }, 2, { 8, 8 } }, - /* A packet split over two transfers, at the USB transport header */ - { "1p2x-split-usbhdr", 1, { 16 }, 2, { 2, 14 } }, - /* A packet split over two transfers, at the MCTP header */ - { "1p2x-split-mctphdr", 1, { 16 }, 2, { 6, 10 } }, /* Single packet split over 3 transfers, middle entirely continuation */ { "1p3x-split", 1, { 12 }, 3, { 4, 4, 4 } }, /* A packet split over 5 transfers, splitting on and between each header.= */ @@ -403,10 +399,73 @@ static const struct mctp_usblib_test_pkt_span mctp_us= blib_test_pkt_spans[] =3D { KUNIT_ARRAY_PARAM(mctp_usblib_test_rx_pkt_span, mctp_usblib_test_pkt_spans, mctp_usblib_test_pkt_span_to_desc); =20 +static void mctp_usblib_test_rx_split_header(struct kunit *test, size_t of= fset, + struct mctp_usblib_test_dev *dev, + struct mctp_usblib_rx *rx) +{ + struct sk_buff *skb; + size_t buflen, len; + u8 packet[16]; + void *buf; + int rc; + + len =3D sizeof(packet); + mctp_usblib_test_init_pkt(packet, len, len); + + rc =3D mctp_usblib_rx_prepare(dev->ndev, rx, &buf, &buflen, GFP_KERNEL); + KUNIT_ASSERT_EQ(test, rc, 0); + KUNIT_ASSERT_GE(test, buflen, len); + + memcpy(buf, packet, offset); + mctp_usblib_test_rx_complete(dev->ndev, rx, offset); + + rc =3D mctp_usblib_rx_prepare(dev->ndev, rx, &buf, &buflen, + GFP_KERNEL); + KUNIT_ASSERT_EQ(test, rc, 0); + KUNIT_ASSERT_GE(test, buflen, len); + KUNIT_ASSERT_EQ(test, dev->rx_pkts.qlen, 0); + + memcpy(buf, packet + offset, len - offset); + mctp_usblib_test_rx_complete(dev->ndev, rx, len - offset); + KUNIT_EXPECT_EQ(test, dev->rx_pkts.qlen, 1); + + skb =3D __skb_dequeue(&dev->rx_pkts); + KUNIT_EXPECT_NOT_NULL(test, skb); + if (skb) { + KUNIT_EXPECT_EQ(test, skb->len, len - HDR_LEN); + kfree(skb); + } +} + +static void mctp_usblib_test_rx_header_splits(struct kunit *test) +{ + struct mctp_usblib_test_dev *dev; + struct mctp_usblib_test_ctx *ctx; + struct mctp_usblib_rx *rx; + size_t i; + + ctx =3D mctp_usblib_test_init(test); + rx =3D mctp_usblib_test_rx_init(test, true); + dev =3D ctx->dev; + + /* Unrolling here so stack traces point to the invocation with the + * failing length. + */ + mctp_usblib_test_rx_split_header(test, 1, dev, rx); + mctp_usblib_test_rx_split_header(test, 2, dev, rx); + mctp_usblib_test_rx_split_header(test, 3, dev, rx); + mctp_usblib_test_rx_split_header(test, 4, dev, rx); + mctp_usblib_test_rx_split_header(test, 5, dev, rx); + mctp_usblib_test_rx_split_header(test, 6, dev, rx); + mctp_usblib_test_rx_split_header(test, 7, dev, rx); + mctp_usblib_test_rx_split_header(test, 8, dev, rx); +} + static struct kunit_case mctp_usblib_test_cases[] =3D { KUNIT_CASE(mctp_usblib_test_rx_single), KUNIT_CASE_PARAM(mctp_usblib_test_rx_pkt_span, mctp_usblib_test_rx_pkt_span_gen_params), + KUNIT_CASE(mctp_usblib_test_rx_header_splits), {} }; =20 --=20 2.47.3 From nobody Sat Sep 26 08:37:37 2026 Received: from codeconstruct.com.au (pi.codeconstruct.com.au [203.29.241.158]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5DF9A19E97B; Thu, 3 Sep 2026 02:42:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.29.241.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403370; cv=none; b=UYGPPsGuS8/Ha9jAFSX3oT0uC94h2L3KPjVzhPShyOSQl59QhceO/NN4joUFMrwNIZ14OhooYaNWENAYAubaMBk7tw9sc9C2nQIxg4MZay7PZh1fIa8yxQ6k/2BQ0HTM6Si0WfEeeUR2/QuXWt3Jnqn+aQi7ZJFqXsX/Sb4mcJk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403370; c=relaxed/simple; bh=tk6ZrQpBluSr4n3qB5Wk1r0PjpZDCcUfDE4f0xeGZNg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=r1gkXCuPismEWP+qhZD5Lwr97bSdGBQbL9YF70npB1QgzxNkFS64VxsmpUG3U6lujCqouuNNGNbX3hyTsD10r6Nov+gky1QX0aMqakH+MNhGBKkjJtfYf5H5FUQnv/4/QppIE0XJziewHP2B97lDsmfJGzGn2VFsDKPIBeMdoWg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au; spf=pass smtp.mailfrom=codeconstruct.com.au; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b=LZctovix; arc=none smtp.client-ip=203.29.241.158 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b="LZctovix" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788403359; bh=+Q8Ci2BqhDAB+rnn+iPJ8rjqbPzcO6kXStVqFYnGwHk=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=LZctovixlGOjCkUxvPPspiuZSrfxJl4skdjectOCjLh3YkflJDshLxZaOYTOz2Pu4 b8PSQrCnB1tjff7aXlmbe2hHHXpOxmJMCstqR0tKnDY8mJdrnDzgh4DoMD9xXutM4Z 8aD8ejip/Lc6JP+b37prGYKGVFNsgjyIjV1ogpv95jdRpaT/CuHuMTAv7ju/OM0SIS USZKj3BZb+Boo1KxqpvqL4aZRh97lim7Sahe0uLtmo8S2Bf+LplAAAeDl+ZT1Uznk0 e22t+K0wFipf8VNblWuB+XBBwMolizftLFfPbk0r4jhtwZg6cIKMJYZKdOFzzB0X48 NngqZP5szJoGw== Received: by codeconstruct.com.au (Postfix, from userid 10004) id C8E4D68693; Thu, 3 Sep 2026 10:42:39 +0800 (AWST) From: James Lee Date: Thu, 03 Sep 2026 10:42:20 +0800 Subject: [PATCH net-next v2 3/7] net: mctp: usblib: Add tests of invalid headers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260903-dev-mctp-usb-lib-test-v2-3-313cf15e0b56@codeconstruct.com.au> References: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> In-Reply-To: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> To: Jeremy Kerr , Matt Johnston , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Kees Cook , "Gustavo A. R. Silva" Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, James Lee X-Mailer: b4 0.14.2 Add tests where the length field of the USB transport header is below the minimum value, and where the DMTF ID is invalid. Signed-off-by: James Lee --- drivers/net/mctp/mctp-usblib-test.c | 69 +++++++++++++++++++++++++++++++++= +++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/net/mctp/mctp-usblib-test.c b/drivers/net/mctp/mctp-us= blib-test.c index a2ca79f61910af129af956a6f38ad69d5dae8c10..b0266be79e94c5adb1cf4286d5a= eef9768d28b34 100644 --- a/drivers/net/mctp/mctp-usblib-test.c +++ b/drivers/net/mctp/mctp-usblib-test.c @@ -442,7 +442,6 @@ static void mctp_usblib_test_rx_header_splits(struct ku= nit *test) struct mctp_usblib_test_dev *dev; struct mctp_usblib_test_ctx *ctx; struct mctp_usblib_rx *rx; - size_t i; =20 ctx =3D mctp_usblib_test_init(test); rx =3D mctp_usblib_test_rx_init(test, true); @@ -461,11 +460,79 @@ static void mctp_usblib_test_rx_header_splits(struct = kunit *test) mctp_usblib_test_rx_split_header(test, 8, dev, rx); } =20 +/* Test the submission of a packet with an impossibly small value in the + * header's length field. Values less than HDR_LEN are invalid. + */ +static void mctp_usblib_test_rx_short_packet(struct kunit *test) +{ + struct mctp_usblib_test_dev *dev; + struct mctp_usblib_test_ctx *ctx; + struct mctp_usblib_rx *rx; + size_t len, buflen; + u8 pktbuf[12]; + void *buf; + int rc; + + ctx =3D mctp_usblib_test_init(test); + rx =3D mctp_usblib_test_rx_init(test, true); + dev =3D ctx->dev; + + len =3D sizeof(pktbuf); + mctp_usblib_test_init_pkt(pktbuf, len, HDR_LEN - 1); + + buflen =3D 0; + rc =3D mctp_usblib_rx_prepare(dev->ndev, rx, &buf, &buflen, GFP_KERNEL); + KUNIT_ASSERT_EQ(test, rc, 0); + KUNIT_ASSERT_GE(test, buflen, len); + + memcpy(buf, pktbuf, len); + + rc =3D mctp_usblib_rx_complete(dev->ndev, rx, len); + KUNIT_EXPECT_EQ(test, rc, -EPROTO); + KUNIT_EXPECT_NULL(test, rx->skb); + KUNIT_EXPECT_EQ(test, dev->rx_pkts.qlen, 0); +} + +static void mctp_usblib_test_rx_invalid_dmtf_id(struct kunit *test) +{ + struct mctp_usblib_test_dev *dev; + struct mctp_usblib_test_ctx *ctx; + struct mctp_usblib_rx *rx; + size_t len, buflen; + u8 pktbuf[12]; + void *buf; + int rc; + + ctx =3D mctp_usblib_test_init(test); + rx =3D mctp_usblib_test_rx_init(test, true); + dev =3D ctx->dev; + + len =3D sizeof(pktbuf); + mctp_usblib_test_init_pkt(pktbuf, len, len); + + // Make packet DMTF ID invalid + pktbuf[1] =3D ~pktbuf[1]; + + buflen =3D 0; + rc =3D mctp_usblib_rx_prepare(dev->ndev, rx, &buf, &buflen, GFP_KERNEL); + KUNIT_ASSERT_EQ(test, rc, 0); + KUNIT_ASSERT_GE(test, buflen, len); + + memcpy(buf, pktbuf, len); + + rc =3D mctp_usblib_rx_complete(dev->ndev, rx, len); + KUNIT_EXPECT_EQ(test, rc, -EPROTO); + KUNIT_EXPECT_NULL(test, rx->skb); + KUNIT_EXPECT_EQ(test, dev->rx_pkts.qlen, 0); +} + static struct kunit_case mctp_usblib_test_cases[] =3D { KUNIT_CASE(mctp_usblib_test_rx_single), KUNIT_CASE_PARAM(mctp_usblib_test_rx_pkt_span, mctp_usblib_test_rx_pkt_span_gen_params), KUNIT_CASE(mctp_usblib_test_rx_header_splits), + KUNIT_CASE(mctp_usblib_test_rx_short_packet), + KUNIT_CASE(mctp_usblib_test_rx_invalid_dmtf_id), {} }; =20 --=20 2.47.3 From nobody Sat Sep 26 08:37:37 2026 Received: from codeconstruct.com.au (pi.codeconstruct.com.au [203.29.241.158]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35A18345EDA; Thu, 3 Sep 2026 02:42:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.29.241.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403371; cv=none; b=eTUWMGIeCC0wRrrspibVgi5nlkw79pvKJG6mHCUz8Y5fpISoStMd89H7gSCY2U14nCyjN+Ly/P7m7Ymka80ljsqqDzNYkXqw6aesrmtj+u4bmr39uUxJfcplgijtLAwmVg9lyxmX3n+H5gUAq6f09PS/zIejaaus3Ktg6MZYl4k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403371; c=relaxed/simple; bh=IQpo3Ur+po/SknYNiFMjOiB665k3pLezpQs8wXnobgc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rCFgtNvWYM1kExbu6GVqV7wtmXg8vz1egmf/AoPwrnlbiBdMNyifbFh7B9AhvRMjwRjUaCGDMBpMSoLeApcd2RrjjQKvRwfjyZNJ1Ktnjng1n0x8PUQBNILKf/OTr4oURxgk4kbgyiOiFHTVmmuyaO0S0LHxhip23Lk80pLJ/cM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au; spf=pass smtp.mailfrom=codeconstruct.com.au; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b=kCBdQRrL; arc=none smtp.client-ip=203.29.241.158 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b="kCBdQRrL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788403360; bh=33Wab9uvJ9ffHBxVA+YFiRSUKBQ8KhuCxK3Ce4oR/nw=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=kCBdQRrLLAoH/lSgdEmNUlmCMef2zXbfghAJcGXPdG6c7xIAtYbRDFnGnrWML2Rje q1LTms+RhQCq/hsvKL6cYtDPz+Ts4IfyuFj2jRj0zfjDxL+EleKlOu9xT2MOj9vNVG jt0eZNNdWzXMe+jKEVJY8FkzcVOTKIzQe/VRrgffTPXMwepZNA/LPw2h9wTlqFbMhQ IjRAukQwWfzedrYBbIw9a8i68HVrkRs93/7uDBnGuJViIObPFq2SjC8z18Z0WEnixU 7Q7IQKGFCeEac1lY+yd4pY7GVpiehEaNNSJNi4yOjfOuNvSQAref+vOb1+38vNgd3H RWJZRtMmetzbA== Received: by codeconstruct.com.au (Postfix, from userid 10004) id 38A0D68694; Thu, 3 Sep 2026 10:42:40 +0800 (AWST) From: James Lee Date: Thu, 03 Sep 2026 10:42:21 +0800 Subject: [PATCH net-next v2 4/7] net: mctp: usblib: Complete rx tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260903-dev-mctp-usb-lib-test-v2-4-313cf15e0b56@codeconstruct.com.au> References: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> In-Reply-To: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> To: Jeremy Kerr , Matt Johnston , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Kees Cook , "Gustavo A. R. Silva" Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, James Lee X-Mailer: b4 0.14.2 Add rx tests without spanning, covering cases where a packet is shorter than allowed without spanning, isn't completed within one submission. Fully cover rx functions except for memory allocation failures and trivial functions. Signed-off-by: James Lee --- drivers/net/mctp/mctp-usblib-test.c | 62 +++++++++++++++++++++++++++++++++= ++++ 1 file changed, 62 insertions(+) diff --git a/drivers/net/mctp/mctp-usblib-test.c b/drivers/net/mctp/mctp-us= blib-test.c index b0266be79e94c5adb1cf4286d5aeef9768d28b34..22aaa4795cbdd13432a3c1e7cc8= 5ecbb3a30fe88 100644 --- a/drivers/net/mctp/mctp-usblib-test.c +++ b/drivers/net/mctp/mctp-usblib-test.c @@ -526,6 +526,66 @@ static void mctp_usblib_test_rx_invalid_dmtf_id(struct= kunit *test) KUNIT_EXPECT_EQ(test, dev->rx_pkts.qlen, 0); } =20 +static void mctp_usblib_test_rx_nonspanning_tiny(struct kunit *test) +{ + struct mctp_usblib_test_dev *dev; + struct mctp_usblib_test_ctx *ctx; + struct mctp_usblib_rx *rx; + size_t len, buflen; + u8 pktbuf[3]; + void *buf; + int rc; + + ctx =3D mctp_usblib_test_init(test); + rx =3D mctp_usblib_test_rx_init(test, false); + dev =3D ctx->dev; + + len =3D sizeof(pktbuf); + mctp_usblib_test_init_pkt(pktbuf, len, len); + + buflen =3D 0; + rc =3D mctp_usblib_rx_prepare(dev->ndev, rx, &buf, &buflen, GFP_KERNEL); + KUNIT_ASSERT_EQ(test, rc, 0); + KUNIT_ASSERT_GE(test, buflen, len); + + memcpy(buf, pktbuf, len); + + rc =3D mctp_usblib_rx_complete(dev->ndev, rx, len); + KUNIT_EXPECT_EQ(test, rc, -ENOMSG); + KUNIT_EXPECT_NULL(test, rx->skb); + KUNIT_EXPECT_EQ(test, dev->rx_pkts.qlen, 0); +} + +static void mctp_usblib_test_rx_nonspanning_partial(struct kunit *test) +{ + struct mctp_usblib_test_dev *dev; + struct mctp_usblib_test_ctx *ctx; + struct mctp_usblib_rx *rx; + size_t len, buflen; + u8 pktbuf[20]; + void *buf; + int rc; + + ctx =3D mctp_usblib_test_init(test); + rx =3D mctp_usblib_test_rx_init(test, false); + dev =3D ctx->dev; + + len =3D sizeof(pktbuf); + mctp_usblib_test_init_pkt(pktbuf, len, len + 1); + + buflen =3D 0; + rc =3D mctp_usblib_rx_prepare(dev->ndev, rx, &buf, &buflen, GFP_KERNEL); + KUNIT_ASSERT_EQ(test, rc, 0); + KUNIT_ASSERT_GE(test, buflen, len); + + memcpy(buf, pktbuf, len); + + rc =3D mctp_usblib_rx_complete(dev->ndev, rx, len); + KUNIT_EXPECT_EQ(test, rc, -EPROTO); + KUNIT_EXPECT_NULL(test, rx->skb); + KUNIT_EXPECT_EQ(test, dev->rx_pkts.qlen, 0); +} + static struct kunit_case mctp_usblib_test_cases[] =3D { KUNIT_CASE(mctp_usblib_test_rx_single), KUNIT_CASE_PARAM(mctp_usblib_test_rx_pkt_span, @@ -533,6 +593,8 @@ static struct kunit_case mctp_usblib_test_cases[] =3D { KUNIT_CASE(mctp_usblib_test_rx_header_splits), KUNIT_CASE(mctp_usblib_test_rx_short_packet), KUNIT_CASE(mctp_usblib_test_rx_invalid_dmtf_id), + KUNIT_CASE(mctp_usblib_test_rx_nonspanning_tiny), + KUNIT_CASE(mctp_usblib_test_rx_nonspanning_partial), {} }; =20 --=20 2.47.3 From nobody Sat Sep 26 08:37:37 2026 Received: from codeconstruct.com.au (pi.codeconstruct.com.au [203.29.241.158]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C255B377A8C; Thu, 3 Sep 2026 02:42:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.29.241.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403374; cv=none; b=q10XqVd3WLUyYAae9C1utZGg5vuU0+V3HYQgw7yyRkn+QpAkRevbiggp+x3B3HCkUdepPn2UXrAYucet2D/OgSkZ3Swg0xyMK9mZPseNQShh30H/cM9EHbLg8dqV6SJ84k9M3AUjrni8Llh/UzVawmLPjuYB6aRFuL29FePU0gc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403374; c=relaxed/simple; bh=rOFunRHFKWI5h6ur/4rVmZMP1w6CoMS/2GbTmoqrM8U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rAvi1wdeUqFm1OpVeNn+AZtqzx+Q+wU6RCYmPtc4Ybi8MCesa0mDjEvqgB2DiJ3V67lFRCvBqyf03zQHDgCnyRtLhzNzgCA2UTzWPbfQbn8KbwBZNe/ZH0/SRBiavD3a2WJaHb2FLFIhKVegQfjzmrm13yPmKrfEtf7erSHtb24= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au; spf=pass smtp.mailfrom=codeconstruct.com.au; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b=UUl36rYV; arc=none smtp.client-ip=203.29.241.158 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b="UUl36rYV" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788403360; bh=aazRtG4rLctFxMuy96ogLq9723zz+Ybi5VOk8UWTfPY=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=UUl36rYVxov/4LQF06r2p/lHZ2IcZPW3XL6CdoSm5n7wqFbJh1rzBdWNXEkJjGIas TT82Yovcfs2c6tUMPmRdLBfVK+UZ3LufNaNnWaQtBP+tyYgsAh4wsYRaJL+Vczl94L 6OCu9HY/NFOpwqhN4x7Lk/+81IOm1OB7owyafbKJsYMJEx5Hg806H9vB2YOrV9i+rB A+cKeSiljCYs9BdWWDJN4Exsm0o3k9Bt+04BB75OrW31CIQAnmxooWPZzF1yHQ/ct2 Bcbsk2gJ7HzDAknrSxmk//pGtMUphC6CefS/Q/MjWzeRVcbDWjRBYw4ZEXXWbLO8iq 5am41GYVIM+pA== Received: by codeconstruct.com.au (Postfix, from userid 10004) id 9339A68695; Thu, 3 Sep 2026 10:42:40 +0800 (AWST) From: James Lee Date: Thu, 03 Sep 2026 10:42:22 +0800 Subject: [PATCH net-next v2 5/7] net: mctp: usblib: Simplify allocation logic in mctp_usblib_test_rx_init Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260903-dev-mctp-usb-lib-test-v2-5-313cf15e0b56@codeconstruct.com.au> References: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> In-Reply-To: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> To: Jeremy Kerr , Matt Johnston , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Kees Cook , "Gustavo A. R. Silva" Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, James Lee X-Mailer: b4 0.14.2 The if statement testing rx's allocation is unneeded. Signed-off-by: James Lee --- drivers/net/mctp/mctp-usblib-test.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/mctp/mctp-usblib-test.c b/drivers/net/mctp/mctp-us= blib-test.c index 22aaa4795cbdd13432a3c1e7cc85ecbb3a30fe88..64c758013854c697767d3cc80d4= 6ebaa310188a4 100644 --- a/drivers/net/mctp/mctp-usblib-test.c +++ b/drivers/net/mctp/mctp-usblib-test.c @@ -202,11 +202,9 @@ mctp_usblib_test_rx_init(struct kunit *test, bool span) int rc; =20 rx =3D kzalloc_obj(*rx); - if (rx) { - rc =3D kunit_add_action_or_reset(test, action_rx_fini, rx); - KUNIT_ASSERT_EQ(test, rc, 0); - } KUNIT_ASSERT_NOT_NULL(test, rx); + rc =3D kunit_add_action_or_reset(test, action_rx_fini, rx); + KUNIT_ASSERT_EQ(test, rc, 0); =20 rc =3D mctp_usblib_rx_init(rx, ep_maxpacket, span); KUNIT_ASSERT_EQ(test, rc, 0); --=20 2.47.3 From nobody Sat Sep 26 08:37:37 2026 Received: from codeconstruct.com.au (pi.codeconstruct.com.au [203.29.241.158]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D0C643783B4; Thu, 3 Sep 2026 02:42:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.29.241.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403375; cv=none; b=gvxY7xphA+rQ/hFP/DFOAfZZb2VV3vZsLtw3z7NCPTu7ZvGUrczp7i+oXN3aJ4efzqvczh7LkP9Lq9Q9FHZ9iXpAfa3KvX50y/dMpzzp1WmAZwK0SIygzHnHdym3aeVBnf0a4n1AKnd1TxKVNyBFxjHYkiyOAt8sXj6ny0sf+eA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403375; c=relaxed/simple; bh=qJ2oHuJ2wmNAoI/KBxN9S2yEYkRgihoqkmyU9c5ngWk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qnorJNEEa2TobB7b9TMwSRb9TMc/vDP3uFVWLoIROczXsdfZ2hZW+AXbMj4ay4PydbW9K+t45AzzQIX8CsP+hg9AnayPJe6+UIXZ0F5MLzY2IQs7fQ9ukdEAM6FtO6XchUgASakf7zMjH+oomycPoZUAywSASfltw9Vh1iyrjQU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au; spf=pass smtp.mailfrom=codeconstruct.com.au; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b=O6jDA5nt; arc=none smtp.client-ip=203.29.241.158 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b="O6jDA5nt" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788403361; bh=AS4RSEAsCORVp176Xj6HC0fiK0ialxjg7zbWbHEE/Po=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=O6jDA5nt55AAErx4/XhwhZCF2q2x8ilgfvf3LAt6JtDoSjBZpifi0aUfMkbx9cWAo Kiy9Q2z3KnTHUEqVUbfcQLzmKGINmIcHf4VQQalmMwSNSdOFmGkQAi2cfMTfFg+v5U cGlGA6awtPb6cklEYXjc+ZiIm3VUnnKHSxE2z8HONoZ80ThFox46ZsJiFEHY3e3npZ g0J6y+DwHf0Qc802mXX29XIFFO0PA/76TdntRMIG47kaspLgHgP91pLRtmFyc4aSqC Oi3TG/JsjCuh00lf9ulNA6XwTU+u35aqeflCz63/wuykYqbY/6levNuU6WkwGOejez QDy7ODD37xpGQ== Received: by codeconstruct.com.au (Postfix, from userid 10004) id 0A2F068696; Thu, 3 Sep 2026 10:42:41 +0800 (AWST) From: James Lee Date: Thu, 03 Sep 2026 10:42:23 +0800 Subject: [PATCH net-next v2 6/7] net: mctp: usblib: Add initial kunit tx tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260903-dev-mctp-usb-lib-test-v2-6-313cf15e0b56@codeconstruct.com.au> References: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> In-Reply-To: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> To: Jeremy Kerr , Matt Johnston , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Kees Cook , "Gustavo A. R. Silva" Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, James Lee X-Mailer: b4 0.14.2 Add tests for the transmit path, where MCTP packets are handed to outgoing USB transfer data. Testing a spanning transfer that is expected to succeed, the failure paths when sends fail, and large sequential sends. Signed-off-by: James Lee --- v2: - Correct flex array reference - Simply return when mctp_usblib_test_tx_send() fails - Use skb_put_data() instead of manual assignment - Remember span parameter exists --- drivers/net/mctp/mctp-usblib-test.c | 286 ++++++++++++++++++++++++++++++++= ++++ 1 file changed, 286 insertions(+) diff --git a/drivers/net/mctp/mctp-usblib-test.c b/drivers/net/mctp/mctp-us= blib-test.c index 64c758013854c697767d3cc80d46ebaa310188a4..73bda4745433f689504e65685b7= 3da2117f1d3db 100644 --- a/drivers/net/mctp/mctp-usblib-test.c +++ b/drivers/net/mctp/mctp-usblib-test.c @@ -6,6 +6,7 @@ * Copyright (C) 2026 Code Construct Pty Ltd */ =20 +#include #include #include #include @@ -16,6 +17,13 @@ =20 #define HDR_LEN sizeof(struct mctp_usb_hdr) =20 +struct tx_buff { + struct list_head list; + + size_t length; + u8 data[] __counted_by(length); +}; + struct mctp_usblib_test_dev { struct net_device *ndev; struct mctp_dev *mdev; @@ -24,9 +32,104 @@ struct mctp_usblib_test_dev { =20 struct mctp_usblib_test_ctx { struct mctp_usblib_test_dev *dev; + struct list_head tx_xfers; struct mctp_route rt; }; =20 +static int mctp_usblib_test_tx_send(struct mctp_usblib_tx_ctx *tx_ctx, + void *data, size_t len) +{ + struct mctp_usblib_test_ctx *ctx; + struct tx_buff *new_node; + struct net_device *ndev; + + ctx =3D mctp_usblib_tx_ctx_priv(tx_ctx); + ndev =3D ctx->dev->ndev; + + new_node =3D kzalloc_flex(*new_node, data, len, GFP_KERNEL); + if (!new_node) + return -ENOMEM; + + new_node->length =3D len; + memcpy(new_node->data, data, len); + list_add_tail(&new_node->list, &ctx->tx_xfers); + + mctp_usblib_tx_send_complete(tx_ctx, ndev, true); + return 0; +} + +static int mctp_usblib_test_tx_send_fail(struct mctp_usblib_tx_ctx *tx_ctx, + void *data, size_t len) +{ + return -ENOMEM; +} + +static u8 *mctp_usblib_test_flatten_tx_buff(struct kunit *test, + struct list_head *in, + size_t *length_out) +{ + struct tx_buff *pos; + size_t length; + u8 *buf, *tail; + + KUNIT_ASSERT_TRUE(test, length_out); + KUNIT_ASSERT_TRUE(test, in); + + length =3D 0; + list_for_each_entry(pos, in, list) + length =3D size_add(length, pos->length); + + KUNIT_ASSERT_NE(test, length, 0); + KUNIT_ASSERT_NE(test, length, SIZE_MAX); + + buf =3D kunit_kzalloc(test, length, GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, buf); + + tail =3D buf; + list_for_each_entry(pos, in, list) { + memcpy(tail, pos->data, pos->length); + tail +=3D pos->length; + } + + *length_out =3D length; + return buf; +} + +static u8 *mctp_usblib_test_init_buf(struct kunit *test, size_t length) +{ + u8 *buffer; + size_t i; + + buffer =3D kunit_kzalloc(test, length, GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, buffer); + + for (i =3D 0; i < length; i++) + buffer[i] =3D i % 256; + + return buffer; +} + +static void mctp_usblib_test_fill_head(struct mctp_usb_hdr *head, size_t l= en) +{ + len +=3D HDR_LEN; + head->id =3D cpu_to_be16(MCTP_USB_DMTF_ID); + head->len =3D cpu_to_be16(len & MCTP_USB_1_1_PKTLEN_MAX); +} + +static struct sk_buff *mctp_usblib_test_init_skb(struct kunit *test, + unsigned int length, + struct net_device *ndev, + void *data) +{ + struct sk_buff *skb; + + skb =3D __netdev_alloc_skb(ndev, length, GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, skb); + + skb_put_data(skb, data, length); + return skb; +} + static netdev_tx_t mctp_usblib_dev_tx(struct sk_buff *skb, struct net_device *ndev) { @@ -119,6 +222,7 @@ static int mctp_usblib_test_dst_output(struct mctp_dst = *dst, static void mctp_usblib_test_fini_action(void *data) { struct mctp_usblib_test_ctx *ctx =3D data; + struct tx_buff *curr, *temp; =20 /* The device will have been destroyed, so ->rt will be unlinked. * Just ensure that the refcount is as expected. @@ -126,6 +230,8 @@ static void mctp_usblib_test_fini_action(void *data) KUNIT_EXPECT_TRUE(current->kunit_test, refcount_dec_and_test(&ctx->rt.refs)); =20 + list_for_each_entry_safe(curr, temp, &ctx->tx_xfers, list) + kfree(curr); kfree(ctx); } =20 @@ -141,6 +247,7 @@ static struct mctp_usblib_test_ctx *mctp_usblib_test_in= it(struct kunit *test) INIT_LIST_HEAD(&ctx->rt.list); rt =3D &ctx->rt; refcount_set(&rt->refs, 1); + INIT_LIST_HEAD(&ctx->tx_xfers); =20 rc =3D kunit_add_action_or_reset(test, mctp_usblib_test_fini_action, ctx); KUNIT_ASSERT_EQ(test, rc, 0); @@ -227,6 +334,32 @@ static int mctp_usblib_test_rx_complete(struct net_dev= ice *netdev, return rc; } =20 +static void action_tx_fini(void *data) +{ + struct mctp_usblib_tx *tx =3D data; + + mctp_usblib_tx_fini(tx); + kfree(tx); +} + +static struct mctp_usblib_tx * +mctp_usblib_test_tx_init(struct kunit *test, + const struct mctp_usblib_tx_ops *ops, + void *priv, bool span) +{ + struct mctp_usblib_tx *tx; + int rc; + + tx =3D kzalloc_obj(*tx); + KUNIT_ASSERT_NOT_NULL(test, tx); + rc =3D kunit_add_action_or_reset(test, action_tx_fini, tx); + KUNIT_ASSERT_EQ(test, rc, 0); + + mctp_usblib_tx_init(tx, ops, priv, span); + + return tx; +} + /* Single packet, starting on a transfer boundary, contained entirely with= in * the transfer */ @@ -584,6 +717,156 @@ static void mctp_usblib_test_rx_nonspanning_partial(s= truct kunit *test) KUNIT_EXPECT_EQ(test, dev->rx_pkts.qlen, 0); } =20 +static void mctp_usblib_test_tx_pkt_span(struct kunit *test) +{ + struct mctp_usblib_test_ctx *ctx; + struct mctp_usblib_tx_ops ops; + struct mctp_usblib_tx *tx; + struct mctp_usb_hdr head; + struct net_device *ndev; + struct sk_buff *skb; + size_t len, tx_len; + u8 *buf, *flat_tx; + int rc; + + len =3D 1000; + + ctx =3D mctp_usblib_test_init(test); + ndev =3D ctx->dev->ndev; + + ops.send =3D mctp_usblib_test_tx_send; + + tx =3D mctp_usblib_test_tx_init(test, &ops, ctx, true); + + buf =3D mctp_usblib_test_init_buf(test, len); + mctp_usblib_test_fill_head(&head, len); + + skb =3D mctp_usblib_test_init_skb(test, len, ndev, buf); + + rc =3D mctp_usblib_tx_push(ndev, tx, skb, false); + KUNIT_ASSERT_EQ(test, rc, 0); + KUNIT_ASSERT_FALSE(test, list_empty(&ctx->tx_xfers)); + + flat_tx =3D mctp_usblib_test_flatten_tx_buff(test, &ctx->tx_xfers, + &tx_len); + KUNIT_ASSERT_NOT_NULL(test, flat_tx); + + KUNIT_EXPECT_EQ(test, tx_len, len + HDR_LEN); + KUNIT_EXPECT_MEMEQ(test, flat_tx, &head, HDR_LEN); + KUNIT_EXPECT_MEMEQ(test, flat_tx + HDR_LEN, buf, len); +} + +static void mctp_usblib_test_tx_failing_send(struct kunit *test) +{ + struct mctp_usblib_test_ctx *ctx; + struct mctp_usblib_tx_ops ops; + struct mctp_usblib_tx *tx; + struct net_device *ndev; + struct sk_buff *skb; + size_t len; + u8 *buf; + int rc; + + len =3D 100; + + ctx =3D mctp_usblib_test_init(test); + ndev =3D ctx->dev->ndev; + + ops.send =3D mctp_usblib_test_tx_send_fail; + + tx =3D mctp_usblib_test_tx_init(test, &ops, ctx, false); + buf =3D mctp_usblib_test_init_buf(test, len); + skb =3D mctp_usblib_test_init_skb(test, len, ndev, buf); + + /* Doesn't call ops.send as more packets are expected, + * so the push shouldn't fail. + */ + rc =3D mctp_usblib_tx_push(ndev, tx, skb, true); + KUNIT_ASSERT_EQ(test, rc, 0); + + skb =3D mctp_usblib_test_init_skb(test, len, ndev, buf); + + /* Calls ops.send as no further packets are expected. */ + rc =3D mctp_usblib_tx_push(ndev, tx, skb, false); + KUNIT_EXPECT_EQ(test, rc, 0); + KUNIT_EXPECT_NULL(test, tx->cur_ctx); + KUNIT_EXPECT_TRUE(test, list_empty(&ctx->tx_xfers)); +} + +/* Test sending multiple packets in the same transfer, followed by one that + * spans multiple subsequent transfers. + */ +static void mctp_usblib_test_tx_multi_push(struct kunit *test) +{ + struct mctp_usblib_test_ctx *ctx; + size_t i, max_length, tx_length; + struct mctp_usblib_tx_ops ops; + u8 *buf, *flat_tx, *index; + struct mctp_usblib_tx *tx; + struct net_device *ndev; + struct sk_buff *skb; + const struct { + size_t len; + bool more; + } sends[] =3D { + { 1000, true }, + { 500, false }, + { 5000, false }, + }; + int rc; + + static_assert(!sends[ARRAY_SIZE(sends) - 1].more, + "The last push must claim there will be no more"); + + max_length =3D 0; + for (i =3D 0; i < ARRAY_SIZE(sends); i++) { + if (sends[i].len > max_length) + max_length =3D sends[i].len; + } + + ctx =3D mctp_usblib_test_init(test); + ndev =3D ctx->dev->ndev; + + ops.send =3D mctp_usblib_test_tx_send; + + tx =3D mctp_usblib_test_tx_init(test, &ops, ctx, true); + buf =3D mctp_usblib_test_init_buf(test, max_length); + + for (i =3D 0; i < ARRAY_SIZE(sends); i++) { + skb =3D mctp_usblib_test_init_skb(test, sends[i].len, ndev, buf); + + rc =3D mctp_usblib_tx_push(ndev, tx, skb, sends[i].more); + KUNIT_ASSERT_EQ(test, rc, 0); + } + KUNIT_ASSERT_FALSE(test, list_empty(&ctx->tx_xfers)); + + flat_tx =3D mctp_usblib_test_flatten_tx_buff(test, &ctx->tx_xfers, + &tx_length); + + for (i =3D 0, index =3D flat_tx; i < ARRAY_SIZE(sends); i++) { + size_t length_to_check, remaining_bytes; + struct mctp_usb_hdr head; + + if (index - flat_tx >=3D tx_length - HDR_LEN) + break; + + mctp_usblib_test_fill_head(&head, sends[i].len); + KUNIT_EXPECT_MEMEQ(test, index, &head, HDR_LEN); + index +=3D HDR_LEN; + remaining_bytes =3D tx_length - (index - flat_tx); + + length_to_check =3D sends[i].len; + KUNIT_EXPECT_GE(test, remaining_bytes, length_to_check); + length_to_check =3D min(remaining_bytes, length_to_check); + + KUNIT_EXPECT_MEMEQ(test, index, + buf, length_to_check); + + index +=3D length_to_check; + } + KUNIT_EXPECT_EQ(test, i, ARRAY_SIZE(sends)); +} + static struct kunit_case mctp_usblib_test_cases[] =3D { KUNIT_CASE(mctp_usblib_test_rx_single), KUNIT_CASE_PARAM(mctp_usblib_test_rx_pkt_span, @@ -593,6 +876,9 @@ static struct kunit_case mctp_usblib_test_cases[] =3D { KUNIT_CASE(mctp_usblib_test_rx_invalid_dmtf_id), KUNIT_CASE(mctp_usblib_test_rx_nonspanning_tiny), KUNIT_CASE(mctp_usblib_test_rx_nonspanning_partial), + KUNIT_CASE(mctp_usblib_test_tx_pkt_span), + KUNIT_CASE(mctp_usblib_test_tx_multi_push), + KUNIT_CASE(mctp_usblib_test_tx_failing_send), {} }; =20 --=20 2.47.3 From nobody Sat Sep 26 08:37:37 2026 Received: from codeconstruct.com.au (pi.codeconstruct.com.au [203.29.241.158]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D1D9E378824; Thu, 3 Sep 2026 02:42:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.29.241.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403374; cv=none; b=O860HLtcDt9k2DmyboN1rLRy6QT0CqvDMM3ucAHENTmYn3QiDNiSce6sggMBGPlrGyi7ECOOmsIgOgP16Jc9KRjOug5AgsSwUsy4Ewqg85GAhEooMZ+9QboJvGSnkf06VFTIoG1AAmZlQVlVGxWyWSDJBKELb50HiiYj1bwaNow= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788403374; c=relaxed/simple; bh=5rdqYpRjHKQgLUsJduiAGoo12p/VCrnSrAA1xfJnwLE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dCTZsyyT6zJjoHG3hV666OJYeP+SaePDj+tdrpz+3XQ45lABiADYLUKmPLzrNCo+lBHy+nBGfQvJxlU1bFBq0vZoU63RAVChuYHav1UcY1B+A/1eaQ9ugR9wlKT/w6xPKkaCMzd4tznUffaOpSQuNIJf5cGHEXUdG7pHt09w9tA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au; spf=pass smtp.mailfrom=codeconstruct.com.au; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b=ZoEFlRvB; arc=none smtp.client-ip=203.29.241.158 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=codeconstruct.com.au Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=codeconstruct.com.au header.i=@codeconstruct.com.au header.b="ZoEFlRvB" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788403361; bh=PlTn3I9kXfPLw7BlbtROwprK/Ezk0JfYuxV+O8GWhsw=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=ZoEFlRvB8IzB36oByjXQ4XOu/gJE0W6Q/1HUjzf11NRG7R+SwjjrdJcWrwWfGbT4T PpvdVoJ5VE/szK4vqmOWf+fBc3+WMqqFKiffCDZeKi1kai+XZ+N7A9OdwPsNShET76 TsIdfGEk7gNfOIkGs5OR/cuuF0G5ERQ0XU9jg1b1bEA/hdtLnGJJwLDAD8FWqzRis9 vHXcmOM5OxiUPR1sbM/NmdOyFG/ZkAamCo2OhtxylYXcYHUzSlT/0vvhhACXZCWOkI LYIqdUQnHT0rE+2c4glepMfUgqXlx4eXqI4OsiBmMRQ9axmps8l2lmvqkx0rWs7nx9 jUK6gf0194bDw== Received: by codeconstruct.com.au (Postfix, from userid 10004) id 63FE068697; Thu, 3 Sep 2026 10:42:41 +0800 (AWST) From: James Lee Date: Thu, 03 Sep 2026 10:42:24 +0800 Subject: [PATCH net-next v2 7/7] net: mctp: usblib: Add test for failing append Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260903-dev-mctp-usb-lib-test-v2-7-313cf15e0b56@codeconstruct.com.au> References: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> In-Reply-To: <20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56@codeconstruct.com.au> To: Jeremy Kerr , Matt Johnston , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Kees Cook , "Gustavo A. R. Silva" Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, James Lee X-Mailer: b4 0.14.2 Add test ensuring that network device stats are updated appropriately when a previously pushed packet fails to send during a subsequent push. Signed-off-by: James Lee --- v2: - Fix preemption management --- drivers/net/mctp/mctp-usblib-test.c | 42 +++++++++++++++++++++++++++++++++= ++++ 1 file changed, 42 insertions(+) diff --git a/drivers/net/mctp/mctp-usblib-test.c b/drivers/net/mctp/mctp-us= blib-test.c index 73bda4745433f689504e65685b73da2117f1d3db..25eac80db3e2d12aabdabbe2342= 61dc335d653b8 100644 --- a/drivers/net/mctp/mctp-usblib-test.c +++ b/drivers/net/mctp/mctp-usblib-test.c @@ -867,6 +867,47 @@ static void mctp_usblib_test_tx_multi_push(struct kuni= t *test) KUNIT_EXPECT_EQ(test, i, ARRAY_SIZE(sends)); } =20 +static void mctp_usblib_test_tx_overflow(struct kunit *test) +{ + struct mctp_usblib_test_ctx *ctx; + struct mctp_usblib_tx_ops ops; + struct pcpu_dstats *dstats; + struct mctp_usblib_tx *tx; + struct net_device *ndev; + struct sk_buff *skb; + unsigned int start; + size_t len, i; + u64 stats; + u8 *buf; + int rc; + + len =3D 200; + + ctx =3D mctp_usblib_test_init(test); + ndev =3D ctx->dev->ndev; + + ops.send =3D mctp_usblib_test_tx_send_fail; + + tx =3D mctp_usblib_test_tx_init(test, &ops, ctx, false); + buf =3D mctp_usblib_test_init_buf(test, len); + + dstats =3D get_cpu_ptr(ndev->dstats); + for (i =3D 0; i < 3; i++) { + skb =3D mctp_usblib_test_init_skb(test, len, ndev, buf); + + rc =3D mctp_usblib_tx_push(ndev, tx, skb, i !=3D 2); + KUNIT_EXPECT_EQ(test, rc, 0); + } + + do { + start =3D u64_stats_fetch_begin(&dstats->syncp); + stats =3D u64_stats_read(&dstats->tx_drops); + } while (u64_stats_fetch_retry(&dstats->syncp, start)); + put_cpu_ptr(dstats); + + KUNIT_EXPECT_EQ(test, stats, 3); +} + static struct kunit_case mctp_usblib_test_cases[] =3D { KUNIT_CASE(mctp_usblib_test_rx_single), KUNIT_CASE_PARAM(mctp_usblib_test_rx_pkt_span, @@ -879,6 +920,7 @@ static struct kunit_case mctp_usblib_test_cases[] =3D { KUNIT_CASE(mctp_usblib_test_tx_pkt_span), KUNIT_CASE(mctp_usblib_test_tx_multi_push), KUNIT_CASE(mctp_usblib_test_tx_failing_send), + KUNIT_CASE(mctp_usblib_test_tx_overflow), {} }; =20 --=20 2.47.3