BPF List
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jiri Olsa" <jolsa@kernel.org>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next 2/4] bpf: Add BPF_TRACE_UPROBE attach type
Date: Tue, 03 Nov 2026 09:59:31 +0000	[thread overview]
Message-ID: <sashiko-outbox-194993@kernel.org> (raw)
In-Reply-To: <20261103093400.112178-3-jolsa@kernel.org>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] bpf: private stack remains enabled for uprobes without BPF_TRACE_UPROBE
- [Medium] bpf: missing BPF_TRACE_UPROBE validation at prog load and attach
--

commit c83a6cf6c87c8d327256fad738b73343332bf238
Author: Jiri Olsa <jolsa@kernel.org>

bpf: Add BPF_TRACE_UPROBE attach type

This commit adds the BPF_TRACE_UPROBE expected attach type for classic uprobe
programs, disables the private stack for programs using it in the verifier,
and rejects attaching them to non-uprobe perf events.

> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index a9c6a4b8eecce..7c941e009a337 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -5707,7 +5707,8 @@ static enum priv_stack_mode bpf_enable_priv_stack(struct bpf_prog *prog)
>  	switch (prog->type) {
>  	case BPF_PROG_TYPE_KPROBE:
>  		/* Disable private stack for uprobe programs. */
> -		if (prog->expected_attach_type == BPF_TRACE_UPROBE_MULTI ||
> +		if (prog->expected_attach_type == BPF_TRACE_UPROBE ||
> +		    prog->expected_attach_type == BPF_TRACE_UPROBE_MULTI ||
>  		    prog->expected_attach_type == BPF_TRACE_UPROBE_SESSION)
>  			return NO_PRIV_STACK;
>  		fallthrough;

[Severity: High]
Can classic uprobe programs still end up with a private stack enabled and
corrupt per-CPU stack state when expected_attach_type is 0?

Classic uprobe programs run via __uprobe_perf_func() ->
bpf_prog_run_array_uprobe() in preemptible (and sleepable when
prog->sleepable is set) context with migrate_disable() and without any
per-CPU recursion guard:

include/linux/bpf.h:bpf_prog_run_array_uprobe() {
	...
	migrate_disable();
	while ((prog = READ_ONCE(item->prog))) {
		if (!prog->sleepable)
			rcu_read_lock();

		run_ctx.bpf_cookie = item->bpf_cookie;
		ret &= run_prog(prog, ctx);
		item++;

		if (!prog->sleepable)
			rcu_read_unlock();
	}
	migrate_enable();
	...
}

If a BPF_PROG_TYPE_KPROBE program with a stack depth of at least
BPF_PRIV_STACK_MIN_SIZE is loaded with expected_attach_type == 0 (including
programs with uprobe-only properties such as prog->sleepable or
prog->aux->kprobe_write_ctx), bpf_enable_priv_stack() still returns
PRIV_STACK_ADAPTIVE.

Even with libbpf updated in the follow-up commit to pass BPF_TRACE_UPROBE,
__perf_event_set_bpf_prog() still permits attaching a BPF_PROG_TYPE_KPROBE
program with expected_attach_type == 0 and prog->aux->jits_use_priv_stack
set to a uprobe perf event. If one task executing the uprobe on a CPU is
preempted or sleeps on a page fault and another task on the same CPU hits the
same uprobe, both tasks will share prog->aux->priv_stack_ptr and overwrite
each other's stack frames.

Should bpf_enable_priv_stack() also check prog->sleepable and
prog->aux->kprobe_write_ctx, and should __perf_event_set_bpf_prog() reject
attaching a program with prog->aux->jits_use_priv_stack to a uprobe perf
event?

> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 457d75ea71420..016d479467edc 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -11835,6 +11835,9 @@ static int __perf_event_set_bpf_prog(struct perf_event *event,
>  	    (is_syscall_tp && prog->type != BPF_PROG_TYPE_TRACEPOINT))
>  		return -EINVAL;
>  
> +	if (prog->expected_attach_type == BPF_TRACE_UPROBE && !is_uprobe)
> +		return -EINVAL;
> +
>  	if (prog->type == BPF_PROG_TYPE_KPROBE && prog->sleepable && !is_uprobe)
>  		/* only uprobe programs are allowed to be sleepable */
>  		return -EINVAL;

[Severity: Medium]
What happens if a non-kprobe program is loaded with BPF_TRACE_UPROBE, or if a
kprobe program with BPF_TRACE_UPROBE is attached via BPF_LINK_CREATE with a
mismatched attach_type?

In kernel/bpf/syscall.c, bpf_prog_load_check_attach() does not restrict
BPF_TRACE_UPROBE to BPF_PROG_TYPE_KPROBE. If a BPF_PROG_TYPE_PERF_EVENT
program is loaded with expected_attach_type == BPF_TRACE_UPROBE and attached
to a non-tracing perf event, __perf_event_set_bpf_prog() returns early before
reaching the new check:

kernel/events/core.c:__perf_event_set_bpf_prog() {
	if (event->state <= PERF_EVENT_STATE_REVOKED)
		return -ENODEV;

	if (!perf_event_is_tracing(event))
		return perf_event_set_bpf_handler(event, prog, bpf_cookie);
	...
	if (prog->expected_attach_type == BPF_TRACE_UPROBE && !is_uprobe)
		return -EINVAL;
}

Additionally, in kernel/bpf/syscall.c, bpf_prog_attach_check_attach_type()
validates BPF_TRACE_KPROBE_MULTI, BPF_TRACE_KPROBE_SESSION,
BPF_TRACE_UPROBE_MULTI, and BPF_TRACE_UPROBE_SESSION under
BPF_PROG_TYPE_KPROBE, but does not check that prog->expected_attach_type ==
BPF_TRACE_UPROBE requires attach_type == BPF_PERF_EVENT:

kernel/bpf/syscall.c:bpf_prog_attach_check_attach_type() {
	...
	case BPF_PROG_TYPE_KPROBE:
		if (prog->expected_attach_type == BPF_TRACE_KPROBE_MULTI &&
		    attach_type != BPF_TRACE_KPROBE_MULTI)
			return -EINVAL;
		if (prog->expected_attach_type == BPF_TRACE_KPROBE_SESSION &&
		    attach_type != BPF_TRACE_KPROBE_SESSION)
			return -EINVAL;
		if (prog->expected_attach_type == BPF_TRACE_UPROBE_MULTI &&
		    attach_type != BPF_TRACE_UPROBE_MULTI)
			return -EINVAL;
		if (prog->expected_attach_type == BPF_TRACE_UPROBE_SESSION &&
		    attach_type != BPF_TRACE_UPROBE_SESSION)
			return -EINVAL;
}

If a BPF_PROG_TYPE_KPROBE program with expected_attach_type ==
BPF_TRACE_UPROBE is passed to link_create() with attach_type set to
BPF_TRACE_KPROBE_MULTI or BPF_TRACE_UPROBE_MULTI, it bypasses
bpf_prog_attach_check_attach_type() and returns -EOPNOTSUPP instead of
-EINVAL when CONFIG_FPROBE or CONFIG_UPROBES is disabled or on 32-bit
architectures.

Should bpf_prog_load_check_attach() and bpf_prog_attach_check_attach_type()
also validate BPF_TRACE_UPROBE?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261103093400.112178-1-jolsa@kernel.org?part=2

  reply	other threads:[~2026-11-03  9:59 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-03  9:33 [PATCH bpf-next 0/4] bpf: Disable private stacks for uprobe programs Jiri Olsa
2026-11-03  9:33 ` [PATCH bpf-next 1/4] bpf: Disable private stack " Jiri Olsa
2026-11-03  9:33 ` [PATCH bpf-next 2/4] bpf: Add BPF_TRACE_UPROBE attach type Jiri Olsa
2026-11-03  9:59   ` sashiko-bot [this message]
2026-11-03  9:33 ` [PATCH bpf-next 3/4] libbpf: Detect BPF_TRACE_UPROBE support Jiri Olsa
2026-11-03  9:54   ` sashiko-bot
2026-11-03  9:34 ` [PATCH bpf-next 4/4] selftests/bpf: Verify classic uprobe attach types Jiri Olsa
2026-11-03  9:56   ` sashiko-bot
2026-11-04  4:33 ` [PATCH bpf-next 0/4] bpf: Disable private stacks for uprobe programs Alexei Starovoitov
2026-11-04 14:17   ` Jiri Olsa

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=sashiko-outbox-194993@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=jolsa@kernel.org \
    --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