All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Andrii Nakryiko <andrii@kernel.org>,
	Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	David Hildenbrand <david@kernel.org>,
	"H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@redhat.com>,
	Jiri Olsa <jolsa@kernel.org>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Paulo Andrade <pandrade@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org, x86@kernel.org
Subject: [BUG] x86: 32-bit uprobes are broken
Date: Wed, 7 Jan 2026 15:32:53 +0100	[thread overview]
Message-ID: <aV5uldEvV7pb4RA8@redhat.com> (raw)

Paulo reported that uprobing the 32-bit tasks is broken.

This script

	#!/usr/bin/bash

	echo 0 > /proc/sys/kernel/randomize_va_space

	echo 'void main(void) {}' > TEST.c

	# -fcf-protection to ensure that the 1st endbr32 insn can't be eulated
	gcc -m32 -fcf-protection=branch TEST.c -o test

	bpftrace -e 'uprobe:./test:main {}' -c ./test

"hangs", the probed ./test task enters the endless loop.

This patch

	--- a/kernel/events/uprobes.c
	+++ b/kernel/events/uprobes.c
	@@ -1710,8 +1710,11 @@ static int xol_add_vma(struct mm_struct *mm, struct xol_area *area)
	 
		if (!area->vaddr) {
			/* Try to map as high as possible, this is only a hint. */
	+		if (test_thread_flag(TIF_ADDR32))
	+			current_thread_info()->status |= TS_COMPAT;
			area->vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE,
							PAGE_SIZE, 0, 0);
	+		current_thread_info()->status &= ~TS_COMPAT;
			if (IS_ERR_VALUE(area->vaddr)) {
				ret = area->vaddr;
				goto fail;

or this one

	--- a/arch/x86/kernel/sys_x86_64.c
	+++ b/arch/x86/kernel/sys_x86_64.c
	@@ -205,6 +205,8 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
			info.low_limit = PAGE_SIZE;
	 
		info.high_limit = get_mmap_base(0);
	+	if (test_thread_flag(TIF_ADDR32))
	+		info.high_limit = current->mm->mmap_compat_base;
		if (!(filp && is_file_hugepages(filp))) {
			info.start_gap = stack_guard_placement(vm_flags);
			info.align_offset = pgoff << PAGE_SHIFT;

"fixes" the problem.

-----------------------------------------------------------------------------------------
The problem is that with randomize_va_space == 0 get_unmapped_area(TASK_SIZE - PAGE_SIZE)
called by xol_add_vma() can't just return the "addr == TASK_SIZE - PAGE_SIZE" hint, this
addr is used by the stack vma.

arch_get_unmapped_area/arch_get_unmapped_area_topdown() doesn't take TIF_ADDR32 into
account and in_32bit_syscall() is false, this leads to info.high_limit > TASK_SIZE.
get_area() happily returns the "high" address and then get_unmapped_area() returns
ENOMEM after the

	if (addr > TASK_SIZE - len)
		return -ENOMEM;

check; TASK_SIZE checks TIF_ADDR32.

handle_swbp() doesn't report this failure (probably it should) and silently restarts
the probed insn. Endless loop.

-----------------------------------------------------------------------------------------
I am considering the patch which adds something like

	// x86 version will use the TS_COMPAT hack
	unsigned long __weak arch_uprobe_area(void)
	{
		return get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
	}

but perhaps there is a better solution? perhaps it makes more sense to change
arch/x86/kernel/sys_x86_64.c? What is the point of ignoring TIF_ADDR32 if the
high adress will be nacked by the "if (addr > TASK_SIZE - len)" check anyway?

Oleg.


             reply	other threads:[~2026-01-07 14:33 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-07 14:32 Oleg Nesterov [this message]
2026-01-07 15:27 ` [BUG] x86: 32-bit uprobes are broken Peter Zijlstra
2026-01-07 15:52   ` Oleg Nesterov
2026-01-10 15:37   ` Oleg Nesterov
2026-01-11 15:00 ` [PATCH] x86/uprobes: Fix XOL allocation failure for 32-bit tasks Oleg Nesterov
2026-01-12 16:40   ` Peter Zijlstra
2026-01-12 17:40     ` Oleg Nesterov
2026-01-14 13:10       ` Oleg Nesterov
2026-01-15 21:43   ` [tip: perf/core] " tip-bot2 for Oleg Nesterov
2026-01-16 10:00     ` Oleg Nesterov
2026-01-16 10:41       ` Peter Zijlstra
2026-01-16 10:49   ` tip-bot2 for Oleg Nesterov
2026-01-16 15:27   ` tip-bot2 for Oleg Nesterov

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=aV5uldEvV7pb4RA8@redhat.com \
    --to=oleg@redhat.com \
    --cc=andrii@kernel.org \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=david@kernel.org \
    --cc=hpa@zytor.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@redhat.com \
    --cc=pandrade@redhat.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --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.