All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yunseong Kim <ysk@kzalloc.com>
To: Will Deacon <will@kernel.org>, Mark Rutland <mark.rutland@arm.com>
Cc: Hemendra Dassanayake <Hemendra.Dassanayake@arm.com>,
	Austin Kim <austindh.kim@gmail.com>,
	Michelle Jin <shjy180909@gmail.com>,
	linux-arm-kernel@lists.infradead.org,
	linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
	Yunseong Kim <ysk@kzalloc.com>, Yeoreum Yun <yeoreum.yun@arm.com>,
	syzkaller@googlegroups.com
Subject: [PATCH] perf: arm_pmuv3: Fix kernel panic on UBSAN from negative hw.idx in armv8pmu_enable/disable_event()
Date: Wed, 23 Jul 2025 10:44:03 +0000	[thread overview]
Message-ID: <20250723104359.364547-5-ysk@kzalloc.com> (raw)

When 'event->hw.idx' was negative in armv8pmu_enable/disable_event().

  UBSAN: shift-out-of-bounds in drivers/perf/arm_pmuv3.c:716:25
  shift exponent -1 is negative

  UBSAN: shift-out-of-bounds in drivers/perf/arm_pmuv3.c:658:13
  shift exponent -1 is negative

This occurred because a perf_event could reach armv8pmu event with a
negative idx, typically when a valid counter could not be allocated.

This issue was observed when running KVM on Radxa's Orion6 platform.

The issue was previously guarded indirectly by armv8pmu_event_is_chained(),
which internally warned and returned false for idx < 0. But since the
commit 29227d6ea157 ("arm64: perf: Clean up enable/disable calls"), this
check was removed.

To prevent undefined behavior, add an explicit guard to early return from
armv8pmu event if hw.idx < 0, similar to handling in other PMU drivers.
(e.g. intel_pmu_disable_event() on arch/x86/events/intel/core.c)

$ ./syz-execprog -executor=./syz-executor -repeat=0  -sandbox=none \
  -disable=binfmt_misc,cgroups,close_fds,devlink_pci,ieee802154,net_dev,net_reset,nic_vf,swap,sysctl,tun,usb,vhci,wifi \
  -procs=8 perf.syz

r0 = perf_event_open(&(0x7f0000000240)={
        0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        @perf_config_ext
    }, 0x0, 0x0, 0xffffffffffffffff, 0x0)

perf_event_open(&(0x7f0000000280)={
        0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        @perf_config_ext
    }, 0x0, 0x0, r0, 0x0)

perf_event_open(&(0x7f0000000540)={
        0x3, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4,
        @perf_bp={0x0, 0x2}, 0x20, 0x0, 0x0, 0x0, 0x2,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x81
    }, 0x0, 0x0, r0, 0x0)

------------[ cut here ]------------
UBSAN: shift-out-of-bounds in drivers/perf/arm_pmuv3.c:716:25
shift exponent -1 is negative
CPU: 0 UID: 0 PID: 8405 Comm: syz.3.19 Tainted: G        W           6.16.0-rc2-g5982a539cdce #3 PREEMPT
Tainted: [W]=WARN
Hardware name: QEMU KVM Virtual Machine, BIOS 2025.02-8 05/13/2025
Call trace:
 show_stack+0x2c/0x3c (C)
 __dump_stack+0x30/0x40
 dump_stack_lvl+0xd8/0x12c
 dump_stack+0x1c/0x28
 ubsan_epilogue+0x14/0x48
 __ubsan_handle_shift_out_of_bounds+0x2b0/0x34c
 armv8pmu_enable_event+0x3c4/0x4b0
 armpmu_start+0xc4/0x118
 perf_event_unthrottle_group+0x3a8/0x50c
 perf_adjust_freq_unthr_events+0x2f4/0x578
 perf_adjust_freq_unthr_context+0x278/0x46c
 perf_event_task_tick+0x394/0x5b0
 sched_tick+0x314/0x6cc
 update_process_times+0x374/0x4b0
 tick_nohz_handler+0x334/0x480
 __hrtimer_run_queues+0x3ec/0xb78
 hrtimer_interrupt+0x2b8/0xb50
 arch_timer_handler_virt+0x74/0x88
 handle_percpu_devid_irq+0x174/0x308
 generic_handle_domain_irq+0xe0/0x140
 gic_handle_irq+0x6c/0x190
 call_on_irq_stack+0x24/0x30
 do_interrupt_handler+0xd4/0x138
 el1_interrupt+0x34/0x54
 el1h_64_irq_handler+0x18/0x24
 el1h_64_irq+0x6c/0x70
 generic_exec_single+0x2dc/0x304 (P)
 smp_call_function_single+0x308/0x530
 perf_install_in_context+0x4a0/0x798
 __arm64_sys_perf_event_open+0x184c/0x1d50
 invoke_syscall+0x98/0x2b8
 el0_svc_common+0x130/0x23c
 do_el0_svc+0x48/0x58
 el0_svc+0x58/0x17c
 el0t_64_sync_handler+0x78/0x108
 el0t_64_sync+0x198/0x19c
---[ end trace ]---
------------[ cut here ]------------
UBSAN: shift-out-of-bounds in drivers/perf/arm_pmuv3.c:658:13
shift exponent -1 is negative
CPU: 0 UID: 0 PID: 8006 Comm: syz.0.19 Not tainted 6.16.0-rc2-g5982a539cdce #3 PREEMPT
Hardware name: QEMU KVM Virtual Machine, BIOS 2025.02-8 05/13/2025
Call trace:
 show_stack+0x2c/0x3c (C)
 __dump_stack+0x30/0x40
 dump_stack_lvl+0xd8/0x12c
 dump_stack+0x1c/0x28
 ubsan_epilogue+0x14/0x48
 __ubsan_handle_shift_out_of_bounds+0x2b0/0x34c
 armv8pmu_disable_event+0x228/0x2f8
 armpmu_stop+0xa0/0x104
 perf_event_throttle_group+0x354/0x4cc
 __perf_event_account_interrupt+0x26c/0x290
 __perf_event_overflow+0xe8/0xd28
 perf_event_overflow+0x38/0x4c
 armv8pmu_handle_irq+0x244/0x320
 armpmu_dispatch_irq+0x6c/0x9c
 handle_percpu_devid_irq+0x174/0x308
 generic_handle_domain_irq+0xe0/0x140
 gic_handle_irq+0x6c/0x190
 call_on_irq_stack+0x24/0x30
 do_interrupt_handler+0xd4/0x138
 el1_interrupt+0x34/0x54
 el1h_64_irq_handler+0x18/0x24
 el1h_64_irq+0x6c/0x70
 generic_exec_single+0x2dc/0x304 (P)
 smp_call_function_single+0x308/0x530
 perf_install_in_context+0x4a0/0x798
 __arm64_sys_perf_event_open+0x184c/0x1d50
 invoke_syscall+0x98/0x2b8
 el0_svc_common+0x130/0x23c
 do_el0_svc+0x48/0x58
 el0_svc+0x58/0x17c
 el0t_64_sync_handler+0x78/0x108
 el0t_64_sync+0x198/0x19c
---[ end trace ]---
------------[ cut here ]------------
UBSAN: shift-out-of-bounds in drivers/perf/arm_pmuv3.c:730:26
shift exponent -1 is negative
CPU: 0 UID: 0 PID: 8006 Comm: syz.0.19 Not tainted 6.16.0-rc2-g5982a539cdce #3 PREEMPT
Hardware name: QEMU KVM Virtual Machine, BIOS 2025.02-8 05/13/2025
Call trace:
 show_stack+0x2c/0x3c (C)
 __dump_stack+0x30/0x40
 dump_stack_lvl+0xd8/0x12c
 dump_stack+0x1c/0x28
 ubsan_epilogue+0x14/0x48
 __ubsan_handle_shift_out_of_bounds+0x2b0/0x34c
 armv8pmu_disable_event+0x298/0x2f8
 armpmu_stop+0xa0/0x104
 perf_event_throttle_group+0x354/0x4cc
 __perf_event_account_interrupt+0x26c/0x290
 __perf_event_overflow+0xe8/0xd28
 perf_event_overflow+0x38/0x4c
 armv8pmu_handle_irq+0x244/0x320
 armpmu_dispatch_irq+0x6c/0x9c
 handle_percpu_devid_irq+0x174/0x308
 generic_handle_domain_irq+0xe0/0x140
 gic_handle_irq+0x6c/0x190
 call_on_irq_stack+0x24/0x30
 do_interrupt_handler+0xd4/0x138
 el1_interrupt+0x34/0x54
 el1h_64_irq_handler+0x18/0x24
 el1h_64_irq+0x6c/0x70
 generic_exec_single+0x2dc/0x304 (P)
 smp_call_function_single+0x308/0x530
 perf_install_in_context+0x4a0/0x798
 __arm64_sys_perf_event_open+0x184c/0x1d50
 invoke_syscall+0x98/0x2b8
 el0_svc_common+0x130/0x23c
 do_el0_svc+0x48/0x58
 el0_svc+0x58/0x17c
 el0t_64_sync_handler+0x78/0x108
 el0t_64_sync+0x198/0x19c
---[ end trace ]---

Fixes: 29227d6ea157 ("arm64: perf: Clean up enable/disable calls")
Signed-off-by: Yunseong Kim <ysk@kzalloc.com>
Tested-by: Yunseong Kim <ysk@kzalloc.com>
Cc: Yeoreum Yun <yeoreum.yun@arm.com>
Cc: syzkaller@googlegroups.com
---
 drivers/perf/arm_pmuv3.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/perf/arm_pmuv3.c b/drivers/perf/arm_pmuv3.c
index 3db9f4ed17e8..846d69643fd8 100644
--- a/drivers/perf/arm_pmuv3.c
+++ b/drivers/perf/arm_pmuv3.c
@@ -795,6 +795,9 @@ static void armv8pmu_enable_user_access(struct arm_pmu *cpu_pmu)
 
 static void armv8pmu_enable_event(struct perf_event *event)
 {
+	if (unlikely(event->hw.idx < 0))
+		return;
+
 	armv8pmu_write_event_type(event);
 	armv8pmu_enable_event_irq(event);
 	armv8pmu_enable_event_counter(event);
@@ -802,6 +805,9 @@ static void armv8pmu_enable_event(struct perf_event *event)
 
 static void armv8pmu_disable_event(struct perf_event *event)
 {
+	if (unlikely(event->hw.idx < 0))
+		return;
+
 	armv8pmu_disable_event_counter(event);
 	armv8pmu_disable_event_irq(event);
 }
-- 
2.50.0



             reply	other threads:[~2025-07-23 11:06 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-23 10:44 Yunseong Kim [this message]
2025-07-23 12:35 ` [PATCH] perf: arm_pmuv3: Fix kernel panic on UBSAN from negative hw.idx in armv8pmu_enable/disable_event() Mark Rutland
2025-07-23 17:39   ` Mark Rutland
2025-07-23 18:57     ` Yunseong Kim
2025-07-24 11:07       ` Mark Rutland
2025-07-24 19:22         ` Yunseong Kim

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=20250723104359.364547-5-ysk@kzalloc.com \
    --to=ysk@kzalloc.com \
    --cc=Hemendra.Dassanayake@arm.com \
    --cc=austindh.kim@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=shjy180909@gmail.com \
    --cc=syzkaller@googlegroups.com \
    --cc=will@kernel.org \
    --cc=yeoreum.yun@arm.com \
    /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.