All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: shaos <shawnq1@163.com>, Jiri Olsa <jolsa@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>
Cc: mhiramat@kernel.org, Peter Zijlstra <peterz@infradead.org>,
	x86@kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [BUG] uprobes/x86: uprobe syscall accepts forged trampoline frames
Date: Tue, 20 Oct 2026 09:42:25 +0200	[thread overview]
Message-ID: <atcbYbiI9Ez5yHhK@redhat.com> (raw)
In-Reply-To: <20261020003704.1012276-1-shawnq1@163.com>

(resend with more CC's)

On 10/20, shaos wrote:
>
> The x86 uprobe syscall checks only that regs->ip lies somewhere in the caller's
> executable [uprobes-trampoline] VMA, then trusts ax, r11, cx and retaddr copied
> from the user stack.  A process can jump into that VMA with a fabricated frame
> and make an enabled uprobe report a hit at a site it never executed, with
> caller-chosen register values.

Yes sure. Userspace can easily fool the sanity checks in in_uprobe_trampoline().
This is a known issue. I think we don't care, and in fact IMO in_uprobe_trampoline()
can die.

At worst this can trigger a wrong a trace event, right? Nothing to fix, I think.

Oleg.

> 
> HEAD commit:    fe2ec83746e501645709761605c2464a44fd2929
> git tree:       upstream Linux checkout, local branch master
> source version: Linux 7.3.0-rc4-70-gfe2ec83746e50
> compiler:       gcc 11.4.0, GNU ld 2.38 (from the kernel build banner)
> 
> console output:
> https://gist.githubusercontent.com/shaos26/82a14d478c3e5b27d81713f9989693cd/raw/9eb4cfbf7c87bf4b06cd6138775a13814ded54c6/console-output.txt
> kernel config:
> https://gist.githubusercontent.com/shaos26/82a14d478c3e5b27d81713f9989693cd/raw/b1d9a09b984075b425aab4875117a6766a795110/kernel-config.txt
> reproducer:
> https://gist.githubusercontent.com/shaos26/82a14d478c3e5b27d81713f9989693cd/raw/b7e400345a004b4a4c340eccad862ac1f569aaee/poc.c
> 
> Build the PoC and run it in a disposable VM with tracefs mounted.  First print the file offsets for site1 and site2, then register and enable a uprobe event at each offset.  The forge mode executes site1 once to map the trampoline, then makes the forged syscall from a uid 65534 child:
> 
>     cc -static -no-pie -O1 -fno-ipa-icf -fno-stack-protector -o forge poc.c
>     mount -t tracefs tracefs /sys/kernel/tracing
>     cp forge /forge
>     /forge offsets
>     echo "p:uprobes/site1 /forge:OFFSET1" > /sys/kernel/tracing/uprobe_events
>     echo "p:uprobes/site2 /forge:OFFSET2" >> /sys/kernel/tracing/uprobe_events
>     echo 1 > /sys/kernel/tracing/events/uprobes/site1/enable
>     echo 1 > /sys/kernel/tracing/events/uprobes/site2/enable
>     echo > /sys/kernel/tracing/trace
>     /forge forge
>     cat /sys/kernel/tracing/trace
> 
> Replace OFFSET1 and OFFSET2 with the file_off1 and file_off2 values printed by /forge offsets.  Run as root for tracefs setup; the PoC drops its forged child to uid 65534.  
> 
> Two fresh boots emitted a trace event for registered site2, which was never executed, and reported attacker-chosen ax/r11/cx values.  Legitimate execution produced only site1; an unregistered offset produced no site2 event; calling uprobe without the trampoline returned EPROTO.
> 
> Impact and prerequisites:
> This falsifies tracing and profiling data for an enabled uprobe in the caller’s address space.  The evidence demonstrates event and register-value forgery, not kernel memory corruption, cross-process data disclosure, or privilege escalation.
> 
> A fix needs to authenticate the probe context before dispatching consumers.  Checking only the trampoline address is insufficient because that mapping is user-executable.
> 
> Validation: Two independent boots emitted a trace event for registered site2, which was never executed, with attacker-chosen register values.  Legitimate site1 execution, an unregistered offset, and a direct syscall without a mapped trampoline served as controls.
> 
> Thanks,
> 
> shaos
.> 


  parent reply	other threads:[~2026-10-20  7:42 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20  0:37 [BUG] uprobes/x86: uprobe syscall accepts forged trampoline frames shaos
2026-10-20  7:39 ` Oleg Nesterov
2026-10-20  7:42 ` Oleg Nesterov [this message]
2026-10-20 15:59   ` Jiri Olsa
2026-10-20  7:48 ` Masami Hiramatsu

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=atcbYbiI9Ez5yHhK@redhat.com \
    --to=oleg@redhat.com \
    --cc=andrii@kernel.org \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=peterz@infradead.org \
    --cc=shawnq1@163.com \
    --cc=x86@kernel.org \
    /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.