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
next 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.