Thank you for your contribution! Sashiko AI review found 4 potential
issue(s) to consider:

Critical: 0 · High: 0 · Medium: 1 · Low: 3

- [Medium] Kernel memory leak in the kunit test helper
  mctp_usblib_test_rx_split_header(): the sk_buff dequeued from…
- [Low] Undisclosed unrelated fixup: this patch silently removes the
  unused `size_t i;` declaration from…
- [Low] Incorrect comment and a test that does not pin the real length
  boundary.
- [Low] mctp_usblib_test_rx_invalid_dmtf_id() introduces a C99 `//`
  comment ("// Make packet DMTF ID invalid"), which checkpatch.pl…

--

net: mctp: usblib: Add tests of invalid headers

Two new kunit cases are added to the mctp-usblib test module: one feeds a
USB transport header whose length field is below the minimum, the other
corrupts the DMTF ID byte.  Both expect mctp_usblib_rx_complete() to
return -EPROTO and to drop the pending skb.

A few questions below.

> diff --git a/drivers/net/mctp/mctp-usblib-test.c 
> b/drivers/net/mctp/mctp-usblib-test.c
> index a2ca79f61910..b0266be79e94 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 
> kunit *test)
>       struct mctp_usblib_test_dev *dev;
>       struct mctp_usblib_test_ctx *ctx;
>       struct mctp_usblib_rx *rx;
> -     size_t i;

[Severity: Low]
Should this removal be squashed into the previous patch of the series?  The
declaration of i in mctp_usblib_test_rx_header_splits() was added by "net:
mctp: usblib: Add test for splits inside headers", and at that commit the
function never references i because the loop is written out as eight
mctp_usblib_test_rx_split_header() calls.  Building that intermediate commit
with CONFIG_MCTP_TRANSPORT_USBLIB_TEST=y should therefore warn with
-Wunused-variable, and the commit message here only mentions the two new
invalid-header tests, not this fixup.

>  
>       ctx = mctp_usblib_test_init(test);
>       rx = mctp_usblib_test_rx_init(test, true);

[Severity: Medium]
While looking at this function, does the helper it calls leak the skb data
buffer?  mctp_usblib_test_rx_split_header() ends with:

        skb = __skb_dequeue(&dev->rx_pkts);
        KUNIT_EXPECT_NOT_NULL(test, skb);
        if (skb) {
                KUNIT_EXPECT_EQ(test, skb->len, len - HDR_LEN);
                kfree(skb);
        }

kfree() returns only the struct sk_buff to the slab; skb_release_all() never
runs, so skb->head and the shinfo dataref are never freed.  The buffer comes
from mctp_usblib_rx_prepare():

        len = rx->span ? roundup(MCTP_USB_1_1_PKTLEN_MAX, rx->ep_pktlen)
                : MCTP_USB_1_0_XFER_SIZE;
        ...
                skb = __netdev_alloc_skb(netdev, len, gfp);

which is roundup(8191, 512) = 8192 bytes per prepared transfer.
mctp_usblib_test_rx_header_splits() calls the helper eight times, so each run
of the case would leak around 64 KiB, and kmemleak/KASAN would attribute it
to the MCTP driver.  mctp_usblib_test_rx_single() and
mctp_usblib_test_rx_pkt_span() both use kfree_skb() here.  The helper came in
with the earlier "net: mctp: usblib: Add test for splits inside headers"
patch and is unchanged at the end of the series, so would a kfree_skb() fixup
there be appropriate?

> @@ -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);
>  }
>  
> +/* Test the submission of a packet with an impossibly small value in the
> + * header's length field. Values less than HDR_LEN are invalid.
> + */

[Severity: Low]
Is "Values less than HDR_LEN are invalid" accurate?  HDR_LEN is
sizeof(struct mctp_usb_hdr), which is 4:

include/linux/usb/mctp-usb.h:
        struct mctp_usb_hdr {
                __be16  id;
                __be16  len;
        } __packed;

but the check being exercised in mctp_usblib_rx_complete() is:

        if (pkt_len < sizeof(*hdr) + sizeof(struct mctp_hdr)) {
                netdev_dbg(netdev, "rx: invalid len %d\n", pkt_len);
                rc = -EPROTO;
                goto err_reset;
        }

so the real minimum is 8, not 4.

> +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 = mctp_usblib_test_init(test);
> +     rx = mctp_usblib_test_rx_init(test, true);
> +     dev = ctx->dev;
> +
> +     len = sizeof(pktbuf);
> +     mctp_usblib_test_init_pkt(pktbuf, len, HDR_LEN - 1);

[Severity: Low]
Following on from the comment above, would pinning the actual boundary give
more coverage here?  HDR_LEN - 1 is 3, which is below both bounds, so the
4..7 range stays untested — including pkt_len == 4, where a header-only
packet would leave a zero-length MCTP packet after
skb_pull(sizeof(struct mctp_usb_hdr)) in mctp_usblib_rx().  If the driver
check were ever relaxed to the weaker bound the comment describes, this case
would still see -EPROTO and pass.  Would rejecting 7 and accepting 8 be a
better test, along with naming HDR_LEN + sizeof(struct mctp_hdr) in the
comment?

> +
> +     buflen = 0;
> +     rc = 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 = 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);
> +}

[ ... ]

> +     len = sizeof(pktbuf);
> +     mctp_usblib_test_init_pkt(pktbuf, len, len);
> +
> +     // Make packet DMTF ID invalid

[Severity: Low]
This isn't a bug, but checkpatch.pl reports "ERROR: do not use C99 //
comments" for this line in mctp_usblib_test_rx_invalid_dmtf_id().  It is the
only // comment in drivers/net/mctp/mctp-usblib-test.c, and it is still
there at the end of the series; could it be converted to /* ... */?

> +     pktbuf[1] = ~pktbuf[1];

[ ... ]

-- 
Sashiko AI review · 
https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56%40codeconstruct.com.au

Reply via email to