From: netdev-bot+sashiko@kernel.org
To: james@codeconstruct.com.au
Cc: jk@codeconstruct.com.au, matt@codeconstruct.com.au,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, kees@kernel.org,
gustavoars@kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org
Subject: Re: [PATCH net-next v2 6/7] net: mctp: usblib: Add initial kunit tx tests
Date: Wed, 09 Sep 2026 05:43:24 +0000 [thread overview]
Message-ID: <178893260401.219967.13741401547777040850@kernel.org> (raw)
In-Reply-To: <20260903-dev-mctp-usb-lib-test-v2-6-313cf15e0b56@codeconstruct.com.au>
Thank you for your contribution! Sashiko AI review found 3 potential
issue(s) to consider:
Critical: 0 · High: 1 · Medium: 0 · Low: 2
- [High] Hard compile error: `static_assert(!sends[ARRAY_SIZE(sends) -
1].more, ...)` in mctp_usblib_test_tx_multi_push()…
- [Low] mctp_usblib_test_tx_multi_push() (drivers/net/mctp/mctp-usblib-
test.c:796-869) is documented as "Test sending multiple packets in the…
- [Low] mctp_usblib_test_tx_send() (drivers/net/mctp/mctp-usblib-
test.c:39-59) calls mctp_usblib_tx_send_complete(tx_ctx, ndev, true)…
--
net: mctp: usblib: Add initial kunit tx tests
This adds KUnit coverage for the mctp-usblib transmit path: a spanning
transfer that is expected to succeed, the failure paths when ops->send
returns an error, and a sequence of larger pushes. The tests record each
->send() call in a list and compare the resulting bytes against the
expected MCTP-over-USB headers and payload.
> diff --git a/drivers/net/mctp/mctp-usblib-test.c b/drivers/net/mctp/mctp-usblib-test.c
> index 64c758013854..73bda4745433 100644
> --- a/drivers/net/mctp/mctp-usblib-test.c
> +++ b/drivers/net/mctp/mctp-usblib-test.c
[ ... ]
> @@ -24,9 +32,104 @@ struct mctp_usblib_test_dev {
>
> struct mctp_usblib_test_ctx {
> struct mctp_usblib_test_dev *dev;
> + struct list_head tx_xfers;
> struct mctp_route rt;
> };
>
> +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 = mctp_usblib_tx_ctx_priv(tx_ctx);
> + ndev = ctx->dev->ndev;
> +
> + new_node = kzalloc_flex(*new_node, data, len, GFP_KERNEL);
> + if (!new_node)
> + return -ENOMEM;
> +
> + new_node->length = 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;
> +}
[Severity: Low]
Is completing the transfer inline here consistent with the documented
ops->send contract?
include/linux/usb/mctp-usb.h says, for struct mctp_usblib_tx_ops::send:
/* Start a USB TX for @data. On returning success, the implementation
* must arrange for mctp_usblib_tx_send_complete() to be called at some
* later point (eg., on urb completion).
*/
mctp_usblib_test_tx_send() instead calls mctp_usblib_tx_send_complete()
(which runs mctp_usblib_tx_stats_update() and mctp_usblib_tx_ctx_free())
and then returns 0, so the tx context is already freed at the point
success is reported. The only in-tree implementer,
mctp_usb_out_complete() in drivers/net/mctp/mctp-usb.c, completes
asynchronously from URB completion.
Nothing breaks today: mctp_usblib_tx_send() reads ctx->tx->ops.send, buf
and ctx->len before the call and only returns the result, and both send
sites in mctp_usblib_tx_push() touch the context afterwards only under
if (rc). But if the library ever legitimately inspects the context after
a successful ->send(), this harness would report it as a KASAN
use-after-free in the test rather than a driver bug.
Would it be better to either record the context and complete it after the
push returns, or to relax the header comment to explicitly allow
synchronous completion?
[ ... ]
> +static u8 *mctp_usblib_test_flatten_tx_buff(struct kunit *test,
> + struct list_head *in,
> + size_t *length_out)
> +{
[ ... ]
> + tail = buf;
> + list_for_each_entry(pos, in, list) {
> + memcpy(tail, pos->data, pos->length);
> + tail += pos->length;
> + }
> +
> + *length_out = length;
> + return buf;
> +}
[ ... ]
> @@ -584,6 +717,156 @@ static void mctp_usblib_test_rx_nonspanning_partial(struct kunit *test)
> KUNIT_EXPECT_EQ(test, dev->rx_pkts.qlen, 0);
> }
>
> +static void mctp_usblib_test_tx_pkt_span(struct kunit *test)
> +{
[ ... ]
> +/* 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)
> +{
[Severity: Low]
Do the assertions in this test actually observe either of the two
properties named in the comment?
mctp_usblib_test_tx_send() records every ops->send() call as its own
tx_buff node, but mctp_usblib_test_flatten_tx_buff() concatenates all of
them into one buffer before any comparison, so the transfer count and the
transfer boundaries are discarded. If mctp_usblib_tx_append() or
mctp_usblib_tx_should_send() regressed and the {1000, true} and
{500, false} packets each went out in their own transfer, the flattened
byte stream would be identical and the test would still pass.
For the second half of the comment, the {5000, false} entry does not span
transfers at the ops layer. mctp_usblib_tx_push() calls
mctp_usblib_tx_ctx_create(tx, skb, single = !more), and:
drivers/net/mctp/mctp-usblib.c:mctp_usblib_tx_ctx_create() {
...
if (single || skb->len > TX_SPAN_MAX) {
type = TX_SINGLE;
} else {
...
}
so with more == false (and skb->len of 5004 exceeding TX_SPAN_MAX anyway)
mctp_usblib_tx_send() issues exactly one ops->send() carrying all 5004
bytes; the library never splits one MCTP packet over several ->send()
calls.
The same naming question applies to mctp_usblib_test_tx_pkt_span(), which
also pushes with more == false and produces a single ->send(), so what it
really covers is the v1.1 13-bit length path in
mctp_usblib_tx_skb_prepare() rather than spanning.
Could the comment and the test names be reworded, and could the
per-transfer boundaries be checked instead of flattened, so the packing
behaviour is actually asserted?
> + 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[] = {
> + { 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");
[Severity: High]
Does this static_assert() compile?
sends[] is a block-scope object with automatic storage duration; the const
qualifier does not make a read of one of its members an integer constant
expression, which is what _Static_assert() requires. include/linux/build_bug.h
expands static_assert() straight through:
#define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr)
#define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
so gcc reports "expression in static assertion is not constant" and clang
reports "static assertion expression is not an integral constant
expression" here.
Because drivers/net/mctp/mctp-usblib.c textually includes this file:
#if IS_ENABLED(CONFIG_MCTP_TRANSPORT_USBLIB_TEST)
#include "mctp-usblib-test.c"
#endif
the failure takes out the whole translation unit, so
drivers/net/mctp/mctp-usblib.o does not build whenever
CONFIG_MCTP_TRANSPORT_USBLIB_TEST is enabled, which is exactly the config
needed to run these tests. The same static_assert is still present in
mctp_usblib_test_tx_multi_push() at the end of the series (7b7c42135cec),
so nothing later in the series fixes it.
Would BUILD_BUG_ON(), which relies on optimizer folding, or a run-time
KUNIT_ASSERT_FALSE(test, sends[ARRAY_SIZE(sends) - 1].more) express the
same invariant?
> +
> + max_length = 0;
> + for (i = 0; i < ARRAY_SIZE(sends); i++) {
> + if (sends[i].len > max_length)
> + max_length = sends[i].len;
> + }
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260903-dev-mctp-usb-lib-test-v2-0-313cf15e0b56%40codeconstruct.com.au
next prev parent reply other threads:[~2026-09-09 5:43 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 2:42 [PATCH net-next v2 0/7] net: mctp: usblib: Increase coverage of kunit testing James Lee
2026-09-03 2:42 ` [PATCH net-next v2 1/7] net: mctp: usblib: Add to parameterized kunit tests James Lee
2026-09-09 5:43 ` netdev-bot+sashiko
2026-09-03 2:42 ` [PATCH net-next v2 2/7] net: mctp: usblib: Add test for splits inside headers James Lee
2026-09-09 5:43 ` netdev-bot+sashiko
2026-09-09 7:12 ` Simon Horman
2026-09-03 2:42 ` [PATCH net-next v2 3/7] net: mctp: usblib: Add tests of invalid headers James Lee
2026-09-09 5:43 ` netdev-bot+sashiko
2026-09-03 2:42 ` [PATCH net-next v2 4/7] net: mctp: usblib: Complete rx tests James Lee
2026-09-09 5:43 ` netdev-bot+sashiko
2026-09-03 2:42 ` [PATCH net-next v2 5/7] net: mctp: usblib: Simplify allocation logic in mctp_usblib_test_rx_init James Lee
2026-09-03 2:42 ` [PATCH net-next v2 6/7] net: mctp: usblib: Add initial kunit tx tests James Lee
2026-09-09 5:43 ` netdev-bot+sashiko [this message]
2026-09-03 2:42 ` [PATCH net-next v2 7/7] net: mctp: usblib: Add test for failing append James Lee
2026-09-09 5:43 ` netdev-bot+sashiko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178893260401.219967.13741401547777040850@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=gustavoars@kernel.org \
--cc=james@codeconstruct.com.au \
--cc=jk@codeconstruct.com.au \
--cc=kees@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=matt@codeconstruct.com.au \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.