Fix a race in the user-callchains code.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAml/E38RHG1pbmdvQGtl
 cm5lbC5vcmcACgkQEnMQ0APhK1gESw/+OvzSQGvWAnL7LDHF5kNvS8eedFQMIXVk
 dkAgQ0ZK2URqU9tJ4RJY8gEAuKwwT+TtA7Ve1vXLYk6s8gpJ5jzYyi760NAbclFj
 JpyPJtS4zIqC2AQD4nMw+xzpLaGjavPN3ewYPdYgnRL2cK2ezZxlxWWxweAShWGH
 CqIXEYxG6Ezx0pUXtgqnUNRNM0ayIWwI8ZDHpvcaFt8FC86aKWvZ4urODGxZAT3Z
 W5JcsJu/cpPjUv4KAkxc9xdeofbPo1YK3yTLA7ih1MsH7p/Q7u5zkNSeXNnF25Wh
 3NrrJCXV3K4MMVwyPQJzoMn8EWsCuP7yeZ5R+ds5aDaOBy4LYoL+kp5HzJ4GzdFr
 YUs3C2cRraR5xB6U9VjgidLNDXIriSUjwj9D9ucV9hlJ3Z7NJw04ZuQP5Oglt1TQ
 Pdndx8OqUyWjBctAOe0+bx6iC40jHrEj9HI3M/LkHM3DVIi5l3KWZi4qTHVTN/f9
 mH5Z4Ot5QSy+A6jFiVXuIfo7CEYow5tOTrEibEX/J5fI5RK/5OgJAPUs+J3VeAMc
 jKb/Hp0e1SbMsoZmggWnNvIUz5Fk6nkkxrvC5iVMuGz6fsD9M7Ms6ckZd3Mw7tpa
 d4F95syN4odTseZX4hMFKyMP8Be62WNXSgXV4a7T8d1+FyYsaEdMRew6pyJD1nUc
 aW5b5eiBeIE=
 =ruON
 -----END PGP SIGNATURE-----

Merge tag 'perf-urgent-2026-02-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf events fix from Ingo Molnar:
 "Fix a race in the user-callchains code"

* tag 'perf-urgent-2026-02-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf: sched: Fix perf crash with new is_user_task() helper
This commit is contained in:
Linus Torvalds 2026-02-01 10:47:21 -08:00
commit c00a879164
3 changed files with 9 additions and 4 deletions

View file

@ -1776,6 +1776,11 @@ static __always_inline bool is_percpu_thread(void)
(current->nr_cpus_allowed == 1);
}
static __always_inline bool is_user_task(struct task_struct *task)
{
return task->mm && !(task->flags & (PF_KTHREAD | PF_USER_WORKER));
}
/* Per-process atomic flags. */
#define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */
#define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */

View file

@ -246,7 +246,7 @@ get_perf_callchain(struct pt_regs *regs, bool kernel, bool user,
if (user && !crosstask) {
if (!user_mode(regs)) {
if (current->flags & (PF_KTHREAD | PF_USER_WORKER))
if (!is_user_task(current))
goto exit_put;
regs = task_pt_regs(current);
}

View file

@ -7460,7 +7460,7 @@ static void perf_sample_regs_user(struct perf_regs *regs_user,
if (user_mode(regs)) {
regs_user->abi = perf_reg_abi(current);
regs_user->regs = regs;
} else if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) {
} else if (is_user_task(current)) {
perf_get_regs_user(regs_user, regs);
} else {
regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE;
@ -8100,7 +8100,7 @@ static u64 perf_virt_to_phys(u64 virt)
* Try IRQ-safe get_user_page_fast_only first.
* If failed, leave phys_addr as 0.
*/
if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) {
if (is_user_task(current)) {
struct page *p;
pagefault_disable();
@ -8215,7 +8215,7 @@ perf_callchain(struct perf_event *event, struct pt_regs *regs)
{
bool kernel = !event->attr.exclude_callchain_kernel;
bool user = !event->attr.exclude_callchain_user &&
!(current->flags & (PF_KTHREAD | PF_USER_WORKER));
is_user_task(current);
/* Disallow cross-task user callchains. */
bool crosstask = event->ctx->task && event->ctx->task != current;
bool defer_user = IS_ENABLED(CONFIG_UNWIND_USER) && user &&