From nobody Sat Sep 26 20:28:01 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 16FBB3BB671; Mon, 31 Aug 2026 03:50:25 +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=1788148229; cv=none; b=oCuLY+p5Z/OqNeFqkjCOLYwaPzf6JjDBnRyE8Dvyvgtgku99bKa849WEw02qOw/4/IOUrHBQyi8CRooL+eNXy0JGb45GEhd2ttUYjFVzmZxt++YSSkBTYItElRwW1l4UkdqUsy4C665NzTbfw8+dFGM0uWszPmHrgy2zEV63t50= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788148229; c=relaxed/simple; bh=T2zwEOSKeJVPvjSKm2GKFRJuXwoncrPadWyEQ19not8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=A5frTtiipyPNbkL5DWfPqSOZZbZd1SyTwuPjo22xnPcGUNuwA8Kfvcr9SyU8aKEstqqxJnCosOuAVIQY0/JKq8N/H4HFo6gBeXv50Zwur14s906dBIqLx/0myOAdoSBDHTLgyTn4WGNFglhf7Uh9GZSBIBHrbH8QI8w1osFvT6w= 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=gyxrraBw; 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="gyxrraBw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788147869; bh=PbFhoF6jYTVQDww2xy+ijFIf+3flRX07CkM/MkYCtcE=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=gyxrraBwUMewyZP9zu2YdxFbIxkpU5oSn9zMlfDLhmvJAQsb/NNDgQPKzoBPYnjis zQWxBBOJ9BAuiCuLrZmJyY3Z92K2sUdikyldhOgBw8n+4lkURcijFoZCdNxLRnpQsp hsXvdXjBT4G+bIIDvzmjU0PhV+WaRGe2T1lou/sp5cWsdCePearGOFvbFF7KeBMSTc RHF8OuP87gmyfr9C3zHwifPDCyxEO9a/rjCe9EbEoKRPeFJtpi0BUw3jdWinilPnu+ +5tbBzlSJJilewX3x6Q4bFgMcujao9Aed0j/NtdqhZhGqW8FyGXBkLgVbBy7o2nO44 d9eNT7Rb1O4FQ== Received: by codeconstruct.com.au (Postfix, from userid 10004) id BAF3F6844B; Mon, 31 Aug 2026 11:44:29 +0800 (AWST) From: James Lee Date: Mon, 31 Aug 2026 11:43:40 +0800 Subject: [PATCH 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: <20260831-dev-mctp-usb-lib-test-v1-1-79699bf67a18@codeconstruct.com.au> References: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@codeconstruct.com.au> In-Reply-To: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@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 20:28:01 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 7DB3B3B993A; Mon, 31 Aug 2026 03:50:25 +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=1788148229; cv=none; b=NuNVmF0O+cZ0MCrubpQr4PgX9fKsHUZRd6P1owjJgzqmHqnN/tIDmqcN4s6BeM5nvd/KO74N1CMACykDFZu1grM4vsFeUs52dqPcq1pzLMoThEiSUKW7LFpEzr24J5Tm2425S6F4BngkJCrk8h9HnK5tWrkUc6/An2MxBIsJu0U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788148229; c=relaxed/simple; bh=e82kdNAHTmo5otX2pNkTZpW60n9WJy57NP28Y++r8Mc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TCtz49l7C2oc8svI0ST3nQ/UCRfr+h4QbGji0NvCo7b/2iaux1njJVatT9gVoYy8cMWZUx6bhqfbzApRcDUKUGIktZvVy3aBIZrk3rnAyehH8ADj0TueUk2lzOo45KYjZgETI/tYcHJf1aZiWE2ozEAVGsFfCc0PkjlnousqK0M= 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=VZi5eg3+; 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="VZi5eg3+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788147870; bh=PX3VN/N7hHR7v61uN6YmJJLT2IKvrpv5bIjy8LQXpbk=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=VZi5eg3+Yc1zFQSprNGWSVOhlHSECKWAhW3Rsjm4d+0Rpe+3PyZsBWngWhT9/DLND c+nv/gj31cH6PdHkQz0BrC9bwGfj2JMmouXZSiwVviUUCxspoiSdaioukKAgORyiNM 9DDH4KnJnk2LUXtzeSznL42dh+3uDo/c5MKritsGoESDBRlx8Q+L+XTcHN6+gU22ua bgN054Z8WRfaaEhaVzV06f8yknRKrFuLi1EXBi4y2m5aLtzmYdUcy+x/G8LHypLe62 456IbmZ0FpTH+zllmKQnlnTWD2xmjSKcY0bBDJOijqqa/3ICXhsC7oDD54lP9RHPiR iVaMRY2gXKzcw== Received: by codeconstruct.com.au (Postfix, from userid 10004) id 489D96844C; Mon, 31 Aug 2026 11:44:30 +0800 (AWST) From: James Lee Date: Mon, 31 Aug 2026 11:43:41 +0800 Subject: [PATCH 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: <20260831-dev-mctp-usb-lib-test-v1-2-79699bf67a18@codeconstruct.com.au> References: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@codeconstruct.com.au> In-Reply-To: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@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 --- drivers/net/mctp/mctp-usblib-test.c | 69 +++++++++++++++++++++++++++++++++= ---- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/drivers/net/mctp/mctp-usblib-test.c b/drivers/net/mctp/mctp-us= blib-test.c index 4c27307900fb6116572bc9d89f3def6f06c30397..1a6dd6d10daab314f5e082477ec= d3b9518f6b50e 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,71 @@ 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_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_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); +} + +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 20:28:01 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 440523A7F75; Mon, 31 Aug 2026 03:50:24 +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=1788148229; cv=none; b=Pm8ri8wX+WOqrnEIoXCRtJPMlNEWyBFcQ5Io/LDiNGgC38dOMpR8JA+Q79wDHKCk+mUHbTNeKxX/fFMoQJDr+1rR+zhUhaMk+Oen0rzruSn8vLhOVmneXdvUu41aP52/PLk6Fy9LeOm95wSk0s7mGVALE4MPSUj6uw8mU2E5UVo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788148229; c=relaxed/simple; bh=131K7gA8Vn3rnDLZncN1xWvIz6Muu3Par0/X49DY8Os=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pdJ1/qd/RI26+7VOxSgFLGZ9jK6dN97e2cIV8M/rftWN5kYBDUI91lMr1+kpj/WMqKALu1FpK9MdtRld+F4TRqu6TKbHC68jipZfn1Mw8XS1Yd7/cT4WKJ1xYNnsjr3zMQaZITXb82bgL3k+H1gXDiHUnoRAX79lNNtSMi4wBmY= 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=chWune1B; 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="chWune1B" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788147870; bh=roJc+Z7MppuQ35gj9+HGSIqbkcKMOueqfabKB3B3kKE=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=chWune1BGAWelCCASy4z2Mw/z4ohSHxLM9a6pFZ4Ul/QbsoGLz2Sz1zSUzu7KXNf4 yuKpXFZ1qBJLKYwfV8LfGEMSCXfYkcmWkyGoP2TG6Nmg22/v/FBPz7dQnqhtSRWFQe D5+ENTFpVrdyWxjiFNY4Caz+W4u3qdD2Mypxx8bNtl9gpsPMgQ5umqU89nrH8ANmYp x5Yi1ss9dOUq8SFEK5fqAyz6M9gS0b0DSo5fajjzbTpK+8CTVwk0QFgP2i8iTYsce6 RJF8nx9bWzmFQQ6uYFCZl1Tfs0QpA18thuFMV0FMrOEWL0tvp8w26Fq7du9OxeQlid 9uGNBz64l5W6g== Received: by codeconstruct.com.au (Postfix, from userid 10004) id 9C4D86844E; Mon, 31 Aug 2026 11:44:30 +0800 (AWST) From: James Lee Date: Mon, 31 Aug 2026 11:43:42 +0800 Subject: [PATCH 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: <20260831-dev-mctp-usb-lib-test-v1-3-79699bf67a18@codeconstruct.com.au> References: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@codeconstruct.com.au> In-Reply-To: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@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 1a6dd6d10daab314f5e082477ecd3b9518f6b50e..4f499de9a6ce4452dcc71ac38fa= 26b6595977f77 100644 --- a/drivers/net/mctp/mctp-usblib-test.c +++ b/drivers/net/mctp/mctp-usblib-test.c @@ -440,7 +440,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); @@ -459,11 +458,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 20:28:01 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 562C33A785C; Mon, 31 Aug 2026 03:50:24 +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=1788148228; cv=none; b=XY2I1tcljXeC6rYoltD4pl9EOVhQX6/yA0DFCb8KgIUa0BvjJ7bjbhptOc9LmQaRRBdLJVtWHuI1en3CKbNC6SK9RMSE39Nfhtkdfsz3vLDoBFC8vG+tFqMU/KlWZzvgRvZAy4Sfj5W7L+U/XwmeTI2I5KFuCcvxKs14lUf6odk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788148228; c=relaxed/simple; bh=E8qTZ7UA+/hkKVCQs3guqOK8eccVNjrxJlYblcrQZX4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dRTF4mSQ/dXsEiPbXwBYhuLAtB7/CX7oJH+JpMmvaIK3MzYfozlPAiPxLGRyg6tLkYj/mwnmz0hBkhHqlATwwoOxxl9SOHsBC7up/qzAaoP8W2K0FfBTzn1fkAeaHmonXHqScxhSP7ONYQWCpERpgas23mPLdtEOXlEiQXBk7LY= 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=fu1Q2VAu; 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="fu1Q2VAu" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788147871; bh=BMi3+MBzg6D9zyId+2HaJdzqPa5Kt7QY4chk34FJAqU=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=fu1Q2VAu8hOa8NNGHQe8RwaTU/vq/+EqSDGv/pbwAAxlvRQjcChm1h0aBr9JViiiE xPzagvyb1vO3nmR7SB6s1jpDfRIaBJaa5Em2A6wosut2/iKLmT70ByZWXT4ylE3iXu mKCGRHZGIhwnvmC/9k73QaWuPPpMOkVHH3aSfxr51DQV8VBSTD65Nu1nCsT+Gr1h67 8+FpMC6JmBtkcvrGk0CMVQDJSPhCCDF3WgwfdttFzbhKyp+vVpYZmSh8xYEJpSUom5 hLAJgOejm6FiQkihgdm2Nv1Qi+kQQ8u/Ao73FjEv1Z7I5RBlWKVvNUm9nSoWehyi10 zN984H+jXT7DA== Received: by codeconstruct.com.au (Postfix, from userid 10004) id 08ACB6844F; Mon, 31 Aug 2026 11:44:31 +0800 (AWST) From: James Lee Date: Mon, 31 Aug 2026 11:43:43 +0800 Subject: [PATCH 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: <20260831-dev-mctp-usb-lib-test-v1-4-79699bf67a18@codeconstruct.com.au> References: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@codeconstruct.com.au> In-Reply-To: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@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 4f499de9a6ce4452dcc71ac38fa26b6595977f77..ab323a31161a415d93eafe4314e= 0e52cedfcd42e 100644 --- a/drivers/net/mctp/mctp-usblib-test.c +++ b/drivers/net/mctp/mctp-usblib-test.c @@ -524,6 +524,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, @@ -531,6 +591,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 20:28:01 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 D3C6C35AC33; Mon, 31 Aug 2026 03:44:41 +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=1788147888; cv=none; b=tjln2ONfVGffok7dNllf9My3a3mjkGe0B/G80r3/cAgspxXXnsLY18DPuiuDqJjbjrGhI+UoHw46R/2CXh4Hw4Xd1J6GEZy/aVWtcr+MvdoZNWjLaciZLtCK+N5CoA+VLoFpQ3KXKyRhF4NWeKhLXEcyhAqNhYAvqgA2kko8kBk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788147888; c=relaxed/simple; bh=V72aHCmF4b7VfASa0RriukX8iwwBYX/nI2WEc7fM5oI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dHtZUanWeM+BwF++hCFCT4HIGCYN+nxMOrppTc7If+BoojBuBspAsYYjwozW7rsDcBi6UyRvlOdXaJ20sDM38q4/XBs42bgtQGbvB6GIAJ0d9BXCYne5hn9ELyPLxoBwJdDEZjDxdVnN3/8/8LVB7k90QoFcVJFD8fl9LVmnTEI= 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=M3T2hIth; 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="M3T2hIth" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788147871; bh=tcBolFJ4EIF2q/e/NdkFEkTsXlaM1Jg3zKGnjeS3tug=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=M3T2hIthfByLiB53LvXYC1lLRJ9iwPqGavMIuY/iRqEuVRNCxkNJDRSbqfqlosVkr yl0sGf/rcW8X1q3cY6M4ObHO1nY+mkXjSZBFyg3qIm/V/UtTFB7nG7ucSqNY7ad9iw 69PLZc4E4NDvOKLCCIHd1sau2tpgbvSV98H7JppBH0vRECNXW59faZDQq1JXCGZ+An Wvmyk7MBTPk3kXC6Nd3HM8eGsI5yaOWR/HHz5VNRuKvq4oaZ+oSkNyF6bfRvWoDWFu U9Fm7Yg2YX9Gbn/k4T7WlOR1+ghJRdP+17bKP+DkSCyFIDVm/CHn3vkvuBrxwzFsxH Zwa1nmrTxjOFQ== Received: by codeconstruct.com.au (Postfix, from userid 10004) id 799F368450; Mon, 31 Aug 2026 11:44:31 +0800 (AWST) From: James Lee Date: Mon, 31 Aug 2026 11:43:44 +0800 Subject: [PATCH 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: <20260831-dev-mctp-usb-lib-test-v1-5-79699bf67a18@codeconstruct.com.au> References: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@codeconstruct.com.au> In-Reply-To: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@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 ab323a31161a415d93eafe4314e0e52cedfcd42e..772484df32a7d7b4d30e51808e0= 6853febe272b6 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 20:28:01 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 D3D0538B14B; Mon, 31 Aug 2026 03:44:41 +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=1788147888; cv=none; b=rmNqXq/y6lZF9j81LKUp9UddRaVChwcs4f53fAPDnDJy3UixfQrAa+MU7aUZ41AcQevCUbu93iXYu39OcMhNSz1SapaDIJS0LLuiSwh+NacMKOvNtsSCloABp47RP4hjhsvVt+2pgvk5dYVtWLQeuT0IS+IKEj8h0zb4BoBaSPQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788147888; c=relaxed/simple; bh=uKH15B5187BJx0Svq0172WuxvKgr+VueTe9NWaQhigc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FZxCbHaHdy1dqCdBDzK2lU5APsBp7ZR3+dsUTIsNPxAGRiQSnx2cXTN/6ENdIj/4UtVcruIOf4+Ga9THf9NuMLVZdnqRb8P2gUSA9PILkXFHaeMb9FN4oyCuvlOoFQsbLGIbWMMWsBvlCcJF/aCRGHQZ1r+3xgc2mmeDgYCEVLQ= 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=XUegohNV; 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="XUegohNV" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788147871; bh=VQpKLCmW4XxE0X+8IaJe5AOkNtk48jbUrUIj5PwR7rE=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=XUegohNVQ1uzixQdwBe43DjEtNseBrtGrzHvJXU8vtok5Yudom8z1xVoUZ4Fqxcb6 thcIwCrS1rWp8+/446DZ0exxNFgK1jfqwOhOmQjZrshZkklOKhY2MDjMrpO091CvIM Ow6pTyhgsba9VEzYdCHgmx3WQTT4/hbv0+jAtwJbA3ZFgSxF3+rTn1d2zyLNNdPlJd mIG6BKxodSgkDX/6OtFL+mlnIZaP8cwS1mntzwRKXxL4FRDYPLnwsmS+PH1x3hne8Z kQGeAagqhKNfwoUueIJYaZagDYb3jo6jQgMxGU+u1iqQ8Zqm14s2idk+Lrla63UWat AHo0DNXqxnqtA== Received: by codeconstruct.com.au (Postfix, from userid 10004) id D787B68451; Mon, 31 Aug 2026 11:44:31 +0800 (AWST) From: James Lee Date: Mon, 31 Aug 2026 11:43:45 +0800 Subject: [PATCH 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: <20260831-dev-mctp-usb-lib-test-v1-6-79699bf67a18@codeconstruct.com.au> References: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@codeconstruct.com.au> In-Reply-To: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@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 --- drivers/net/mctp/mctp-usblib-test.c | 292 ++++++++++++++++++++++++++++++++= ++++ 1 file changed, 292 insertions(+) diff --git a/drivers/net/mctp/mctp-usblib-test.c b/drivers/net/mctp/mctp-us= blib-test.c index 772484df32a7d7b4d30e51808e06853febe272b6..7dc382caffc17644dd616f78df3= 32201d412f709 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,110 @@ 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; + int rc; + + ctx =3D mctp_usblib_tx_ctx_priv(tx_ctx); + ndev =3D ctx->dev->ndev; + rc =3D 0; + + new_node =3D kzalloc_flex(*new_node, data, len, GFP_KERNEL); + if (!new_node) { + rc =3D -ENOMEM; + goto exit; + } + + new_node->length =3D len; + memcpy(&new_node->data, data, len); + list_add_tail(&new_node->list, &ctx->tx_xfers); + +exit: + mctp_usblib_tx_send_complete(tx_ctx, ndev, rc =3D=3D 0); + return rc; +} + +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->len =3D length; + memcpy(skb->data, data, length); + return skb; +} + static netdev_tx_t mctp_usblib_dev_tx(struct sk_buff *skb, struct net_device *ndev) { @@ -119,6 +228,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 +236,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 +253,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 +340,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, true); + + return tx; +} + /* Single packet, starting on a transfer boundary, contained entirely with= in * the transfer */ @@ -582,6 +721,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, @@ -591,6 +880,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 20:28:01 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 870733A6F1B; Mon, 31 Aug 2026 03:44:46 +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=1788147897; cv=none; b=u+asHK2YPiZfGXpNqkosN/oIXcjlwXKhdRJL9xntPGFUHhl8OJPN17YqzfnnYIzU+MlZB43JsnhxSRbuL9sJ2pfVQssDToVZpQyvAGGbnqqbMnvmCU+rlJceDSAuJi9QKsPhI5uRhwwHkaScKpjZieEgFlBc1HQ7brJ3HpnN/M8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788147897; c=relaxed/simple; bh=+BkdD5eC3Hp6UHH6ztBtLCKcezhYUQWiO5tEFxsoK5U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BzIy3N7VtnZAblOUPmwqq/QWbhCNNsiRrP7dyzgOFvyXZEYvqUJmchyRmJa3wFN6qVzjTcjTsmvteQA/f/Q+p6jft5vshd8g6HrdXUuBD04wOUql2RHoBLFlabhPg0Iauy0eCTwNfhYjTh1qzbZ6mjuKAxdC2Aple9/CBm/l/L4= 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=Q8uXOHDt; 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="Q8uXOHDt" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeconstruct.com.au; s=2022a; t=1788147872; bh=3rfQrxzu7Qf878wkK4gzC32M3ksdn/bsvmrudPevC7U=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=Q8uXOHDtaGgudD7jUjfUT4be+V1h4asBDl8ZZ2cGw9jQUGO92vUynoAC/mcll0Jua TGSNP5+4EHx5Qi7XNw2kssrrdjXwThi3JdZypf593IJyS5d9duE6eJDdmKPF4uQ3X3 27yt2Ff7rqvi+1a2zGfpRGv1LqlbAn1colqTv2/nAsAxce8gI/6owNkuQJdOwYbGf+ mHxkfimuM1ovei5Wgmksd/YMi95tZp3oeiXyEmmD0fjrvS9wbQDFdRs9PHA47SoE5+ LF43lIYDoFozeQMAwQlR2Lj7ZM5w7Lb14wnF3dL3tIFfMY2VIibUGnjL+7CL60Rcx4 pBZ9PO1fecQmw== Received: by codeconstruct.com.au (Postfix, from userid 10004) id 4B52B68452; Mon, 31 Aug 2026 11:44:32 +0800 (AWST) From: James Lee Date: Mon, 31 Aug 2026 11:43:46 +0800 Subject: [PATCH 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: <20260831-dev-mctp-usb-lib-test-v1-7-79699bf67a18@codeconstruct.com.au> References: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@codeconstruct.com.au> In-Reply-To: <20260831-dev-mctp-usb-lib-test-v1-0-79699bf67a18@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 --- 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 7dc382caffc17644dd616f78df332201d412f709..b3a2cc5cbd99defde308cf23a1b= 559dbdc73ca22 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 "linux/percpu-defs.h" #include #include #include @@ -871,6 +872,46 @@ 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); + + 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); + } + + dstats =3D get_cpu_ptr(ndev->dstats); + 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)); + + 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, @@ -883,6 +924,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