The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Harry Yoo (Oracle)" <harry@kernel.org>
Cc: linux-rt-devel@lists.linux.dev, linux-kernel@vger.kernel.org,
	bpf@vger.kernel.org
Subject: Re: [PATCH v5 1/8] mm/slab, slub_kunit: register kprobe to trigger _nolock APIs
Date: Wed, 29 Jul 2026 08:35:30 +0000	[thread overview]
Message-ID: <20260729083530.B3E2B1F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260729-kfree_rcu_nolock-v5-1-a28cdcda9673@kernel.org>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Manual cleanup of global kprobe leads to stack Use-After-Free if the KUnit test aborts.
- [Medium] Global kprobe registration causes concurrent data races and triggers test allocations from unrelated system processes.
--

--- Patch [1]: [PATCH v5 1/8] mm/slab, slub_kunit: register kprobe to trigger _nolock APIs ---
commit a8a477af9c0547e09308b4a325920cd9de52b25e
Author: Harry Yoo (Oracle) <harry@kernel.org>

    mm/slab, slub_kunit: register kprobe to trigger _nolock APIs
    
    Since kmalloc_nolock() always fails in NMI and hardirq contexts on
    PREEMPT_RT, slub_kunit cannot properly test _nolock() APIs.
    
    Register a kprobe pre-handler to invoke kmalloc_nolock() and
    kfree_nolock() in the middle of the slab allocator.
    
    Link: https://lore.kernel.org/linux-mm/20260427-nolock-api-fix-v2-0-a6b83a92d9a4@kernel.org [1]
    Link: https://lore.kernel.org/linux-mm/6edebc2b-5f5a-4b9c-9a4c-564310acee1b@kernel.org  [2]

> diff --git a/lib/tests/slub_kunit.c b/lib/tests/slub_kunit.c
> index fa6d31dbca166..8c2b9911471eb 100644
> --- a/lib/tests/slub_kunit.c
> +++ b/lib/tests/slub_kunit.c

[ ... ]

> +#if defined(CONFIG_KPROBES) && defined(CONFIG_SMP)
> +static int slab_kprobe_pre_handler(struct kprobe *p, struct pt_regs *regs)
> +{
> +	struct test_nolock_context *ctx;
> +
> +	ctx = container_of(p, struct test_nolock_context, kprobe);
> +	test_nolock(ctx);

[Severity: Medium]
Will this handler execute unconditionally for any task that hits the kprobe?

The kprobe is registered globally on slab_attach_kprobe_locked(). Since this
function is inserted into slab_lockdep_assert_held(), which is heavily used
in the slab allocator's paths, any task on any CPU performing an allocation
can trigger the kprobe.

This allows unrelated system processes to execute the test logic concurrently.
Does this code need a check to restrict execution to the test thread, such as
verifying current against the test task?

Additionally, this can cause data races in test_nolock() since unrelated
system processes would perform unsynchronized read-modify-write operations on
the stack-allocated ctx variables:

lib/tests/slub_kunit.c:test_nolock() {
    ...
    if (objp)
        ctx->alloc_ok++;
    else
        ctx->alloc_fail++;
    ...
}

> +	return 0;
> +}
> +
> +static bool register_slab_kprobes(struct test_nolock_context *ctx)
> +{
> +	ctx->kprobe.symbol_name = "slab_attach_kprobe_locked";
> +	ctx->kprobe.pre_handler = slab_kprobe_pre_handler;
> +
> +	if (register_kprobe(&ctx->kprobe))
> +		return false;
> +	return true;
> +}

[ ... ]

> +static void test_kmalloc_kfree_nolock_kprobe(struct kunit *test)
> +{
> +	struct test_nolock_context ctx = { .test = test };
>  
> -cleanup:
> -	perf_event_disable(ctx.event);
> -	perf_event_release_kernel(ctx.event);
> +	if (!register_slab_kprobes(&ctx))
> +		kunit_skip(test, "Failed to register kprobe, skipping");
>  
> -	kunit_info(test, "callback_count: %d, alloc_ok: %d, alloc_fail: %d\n",
> -		   ctx.callback_count, ctx.alloc_ok, ctx.alloc_fail);
> +	test_kmalloc_kfree();
>  
> -	if (alloc_fail)
> -		kunit_skip(test, "Allocation failed");
> +	unregister_slab_kprobes(&ctx);

[Severity: High]
Can this manual unregistration lead to a stack use-after-free if the KUnit
test aborts before completing?

If the test aborts (for example, due to a KUnit timeout which is possible
given the system-wide contention caused by the global kprobe), the thread
could exit and its stack memory would be freed, bypassing this manual
cleanup.

If the global kprobe remains active and continues to fire for other tasks,
would the pre-handler then dereference the ctx pointer, pointing to freed
stack memory?

Could kunit_add_action() be used to ensure the cleanup is always executed
even if the test aborts?

>  	KUNIT_EXPECT_EQ(test, 0, slab_errors);
>  }
>  #endif

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260729-kfree_rcu_nolock-v5-0-a28cdcda9673@kernel.org?part=1

  reply	other threads:[~2026-07-29  8:35 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-29  8:20 [PATCH v5 0/8] mm/slab: introduce kfree_rcu_nolock() and improve slub_kunit coverage Harry Yoo (Oracle)
2026-07-29  8:20 ` [PATCH v5 1/8] mm/slab, slub_kunit: register kprobe to trigger _nolock APIs Harry Yoo (Oracle)
2026-07-29  8:35   ` sashiko-bot [this message]
2026-07-29  8:20 ` [PATCH v5 2/8] mm/slab: handle the !allow_spin case in kfree_rcu_sheaf() Harry Yoo (Oracle)
2026-07-29  8:44   ` sashiko-bot
2026-07-29  8:20 ` [PATCH v5 3/8] mm/slab: use call_rcu() in unknown context if irqs are enabled Harry Yoo (Oracle)
2026-07-29  8:47   ` sashiko-bot
2026-07-29  8:20 ` [PATCH v5 4/8] mm/slab: extend deferred free mechanism to handle rcu sheaves Harry Yoo (Oracle)
2026-07-29  8:20 ` [PATCH v5 5/8] mm/slab: allow kfree_rcu_sheaf() on PREEMPT_RT Harry Yoo (Oracle)
2026-07-29  8:43   ` sashiko-bot
2026-07-29  8:20 ` [PATCH v5 6/8] mm/slab: introduce struct kvfree_rcu_head for kvfree_rcu batching Harry Yoo (Oracle)
2026-07-29  8:40   ` sashiko-bot
2026-07-29  8:20 ` [PATCH v5 7/8] mm/slab: introduce kfree_rcu_nolock() Harry Yoo (Oracle)
2026-07-29  8:41   ` sashiko-bot
2026-07-29  8:20 ` [PATCH v5 8/8] slub_kunit: extend the test for kfree_rcu_nolock() Harry Yoo (Oracle)
2026-07-29  8:39   ` sashiko-bot

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=20260729083530.B3E2B1F00A3D@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=harry@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rt-devel@lists.linux.dev \
    --cc=sashiko-reviews@lists.linux.dev \
    /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