lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20260205110855.GJ232055@noisy.programming.kicks-ass.net>
Date: Thu, 5 Feb 2026 12:08:55 +0100
From: Peter Zijlstra <peterz@...radead.org>
To: Zw Tang <shicenci@...il.com>
Cc: "linux-perf-users@...r.kernel.org" <linux-perf-users@...r.kernel.org>,
	mingo@...hat.com, boqun.feng@...il.com,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
	namhyung@...nel.org, will@...nel.org, juri.lelli@...hat.com
Subject: Re: [BUG] PREEMPT_RT: sleeping function called from invalid context
 in perf_event_wakeup()

On Thu, Feb 05, 2026 at 06:42:05PM +0800, Zw Tang wrote:
> Hi,
> 
> I am reporting a PREEMPT_RT “sleeping function called from invalid
> context” bug triggered by a syzkaller reproducer on Linux 6.19.0-rc7.
> 
> The kernel reports:
> 
> BUG: sleeping function called from invalid context at
> kernel/locking/spinlock_rt.c:48
> in_atomic(): 1, irqs_disabled(): 1, preempt_count: 4
> 
> The splat points to perf’s wakeup path taking an RT spinlock while
> running in an atomic/IRQs-disabled context:
> 
> merge_sched_in()
> -> perf_event_wakeup()
> -> __wake_up_common_lock()
> -> rt_spin_lock()
> -> __might_resched() (complains about sleeping in invalid context)
> 
> This suggests a locking semantic mismatch on PREEMPT_RT:
> perf_event_wakeup() (via __wake_up_common_lock()) ends up taking a
> lock that maps to rt_spin_lock(), which may sleep on RT kernels, but
> the current context is explicitly atomic with IRQs disabled.

Fixes: f4b07fd62d4d ("perf/core: Use POLLHUP for pinned events in error")

diff --git a/kernel/events/core.c b/kernel/events/core.c
index dad0d3d2e85f..216cf6ae1c7d 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4017,7 +4017,8 @@ static int merge_sched_in(struct perf_event *event, void *data)
 			if (*perf_event_fasync(event))
 				event->pending_kill = POLL_ERR;
 
-			perf_event_wakeup(event);
+			event->pending_wakeup = 1;
+			irq_work_queue(&event->pending_irq);
 		} else {
 			struct perf_cpu_pmu_context *cpc = this_cpc(event->pmu_ctx->pmu);

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ