From: James Lee <james@codeconstruct.com.au>
To: netdev-bot+sashiko@kernel.org
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 7/7] net: mctp: usblib: Add test for failing append
Date: Tue, 13 Oct 2026 17:06:06 +0800 [thread overview]
Message-ID: <09f81599d3272e23fb4cffbbff669021d9c9b204.camel@codeconstruct.com.au> (raw)
In-Reply-To: <178893260523.219967.7691706807394215121@kernel.org>
> [Severity: Low]
> This isn't a bug, but len = 200 and the loop count of 3 below
> silently
> encode a dependency on MCTP_USB_1_0_XFER_SIZE (512) and MCTP_USB_BTU,
> without referencing either constant.
>
> I traced the intended path and it does run today with span=false:
> each skb
> becomes 204 bytes after mctp_usblib_tx_skb_prepare() pushes the 4-
> byte
> header, push 1 creates the 512-byte ctx, push 2 appends (len 408,
> avail
> 104), and push 3 hits mctp_usblib_tx_append():
>
> if (mctp_usblib_tx_avail(ctx) < skb->len)
> return -ENOBUFS;
>
> with avail 104 < skb->len 204.
>
> Could len and the iteration count be derived from
> MCTP_USB_1_0_XFER_SIZE / MCTP_USB_BTU instead, so the case keeps
> hitting
> the append-failure branch if those change?
>
> Also, would tx_overflow be better named after the append failure the
> commit subject describes?
>
Valid catch, will rename and remove the magic constants.
>
> [Severity: High]
> Can this sleep with preemption disabled? get_cpu_ptr() expands to
> preempt_disable() plus this_cpu_ptr(), so the whole loop runs in
> atomic
> context, and mctp_usblib_test_init_skb() allocates with GFP_KERNEL:
>
> drivers/net/mctp/mctp-usblib-test.c:mctp_usblib_test_init_skb() {
> skb = __netdev_alloc_skb(ndev, length, GFP_KERNEL);
> KUNIT_ASSERT_NOT_NULL(test, skb);
> ...
> }
>
> GFP_KERNEL sets __GFP_DIRECT_RECLAIM, so __netdev_alloc_skb() takes
> the
> blocking slab path:
>
> net/core/skbuff.c:__netdev_alloc_skb() {
> if (len <= SKB_WITH_OVERHEAD(SKB_SMALL_HEAD_CACHE_SIZE) ||
> len > SKB_WITH_OVERHEAD(PAGE_SIZE) ||
> (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA))) {
> skb = __alloc_skb(len, gfp_mask, SKB_ALLOC_RX,
> NUMA_NO_NODE);
> ...
> }
>
> With CONFIG_DEBUG_ATOMIC_SLEEP, wouldn't the might_sleep() in the
> allocator produce a "sleeping function called from invalid context"
> splat
> every time this case runs?
>
> Two further consequences of the same region:
>
> The KUNIT_ASSERT_NOT_NULL() in mctp_usblib_test_init_skb() and the
> KUnit
> failure reporting behind KUNIT_EXPECT_EQ() also allocate with
> GFP_KERNEL,
> and the assert variant does not return:
>
> lib/kunit/try-catch.c:kunit_try_catch_throw() {
> try_catch->try_result = -EFAULT;
> kthread_exit(0);
> }
>
> so put_cpu_ptr() below is skipped and the thread exits still in
> atomic
> context, which kernel/exit.c reports:
>
> kernel/exit.c:do_exit() {
> if (unlikely(in_atomic())) {
> pr_info("note: %s[%d] exited with preempt_count
> %d\n",
> current->comm, task_pid_nr(current),
> preempt_count());
> preempt_count_set(PREEMPT_ENABLED);
> }
> ...
> }
>
> mctp_usblib_tx_push() also takes a spinlock_t here:
>
> drivers/net/mctp/mctp-usblib.c:mctp_usblib_tx_push() {
> spin_lock_irqsave(&tx->lock, flags);
> ...
> }
>
> On PREEMPT_RT that is a sleeping lock, so is acquiring it from an
> explicitly preempt-disabled section valid?
>
> Note the driver itself uses GFP_ATOMIC on this path
> (mctp_usblib_tx_ctx_create() uses kzalloc_flex(..., GFP_ATOMIC)), so
> only
> the test's own allocation is out of context.
>
> Since mctp_usblib_tx_stats_update() picks the counter with
> get_cpu_ptr(dev->dstats), could the skb allocation and the assertions
> move
> outside the pinned region, leaving only the counter read inside
> get_cpu_ptr()/put_cpu_ptr(), or could tx_drops be summed over
> for_each_possible_cpu() instead?
Good catch, will correct.
> [Severity: Low]
> This is the same finding as the len = 200 comment above: this
> aggregate
> drop count is the only oracle in the case.
>
> The append-failure path yields 2 drops from the detached two-skb
> context
> plus 1 from the single-skb context, but so do other paths: if the ctx
> buffer size grew, if the MCTP_USB_BTU margin in
> mctp_usblib_tx_should_send() changed so the ctx flushed after push 2,
> or
> if all three skbs fit one ctx, the append branch never runs and stats
> is
> still 3.
>
> Neither the number of ops.send() invocations, nor tx->cur_ctx, nor
> ctx->tx_xfers is checked here, while the neighbouring
> mctp_usblib_test_tx_failing_send() does:
>
> KUNIT_EXPECT_EQ(test, rc, 0);
> KUNIT_EXPECT_NULL(test, tx->cur_ctx);
> KUNIT_EXPECT_TRUE(test, list_empty(&ctx->tx_xfers));
>
> Would checking tx_drops == 0 after the first two pushes and counting
> the
> send attempts (2 sends carrying 2 and 1 packets) pin down the branch
> under
> test?
Fair point, will begin checking for expected behaviour between sends as
well.
prev parent reply other threads:[~2026-10-13 9:06 UTC|newest]
Thread overview: 17+ 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-14 3:14 ` James Lee
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
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
2026-10-13 9:06 ` James Lee [this message]
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=09f81599d3272e23fb4cffbbff669021d9c9b204.camel@codeconstruct.com.au \
--to=james@codeconstruct.com.au \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=gustavoars@kernel.org \
--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-bot+sashiko@kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®