Re: [PATCH 8/8] perf/core: Fix kernel register info leak via hardware skid
From: Mi, Dapeng
Date: Sun Jun 07 2026 - 22:49:33 EST
On 6/6/2026 3:08 AM, Falcon, Thomas wrote:
> On Fri, 2026-06-05 at 09:11 +0800, Dapeng Mi wrote:
>> An unprivileged hardware perf event using exclude_kernel=1 can leak
>> kernel
>> register data to user space via PERF_SAMPLE_REGS_INTR. Due to
>> hardware
>> skid, a PMI may trigger after the CPU has already entered kernel
>> space
>> (Ring 0), bypassing the perf_allow_kernel() privilege barrier.
>>
>> This security vulnerability is severely exacerbated by upcoming
>> support
>> for SIMD register sampling via XSAVES, which could expose sensitive
>> kernel
>> FPU states (such as active cryptographic keys).
>>
>> Fix this by ensuring that sampled register data is dropped if the
>> event's
>> exclude_kernel attribute is set but the PMI catches the CPU in kernel
>> mode.
>>
>> Link:
>> https://lore.kernel.org/all/20260529085613.CCAFB1F00893@xxxxxxxxxxxxxxx/
>> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
>> Cc: Mark Rutland <mark.rutland@xxxxxxx>
>> Signed-off-by: Dapeng Mi <dapeng1.mi@xxxxxxxxxxxxxxx>
>> ---
>> kernel/events/core.c | 20 ++++++++++++++++----
>> 1 file changed, 16 insertions(+), 4 deletions(-)
>>
>> diff --git a/kernel/events/core.c b/kernel/events/core.c
>> index 7935d5663944..b7326bc3acd0 100644
>> --- a/kernel/events/core.c
>> +++ b/kernel/events/core.c
>> @@ -7800,10 +7800,21 @@ static void perf_sample_regs_user(struct
>> perf_regs *regs_user,
>> }
>>
>> static void perf_sample_regs_intr(struct perf_regs *regs_intr,
>> - struct pt_regs *regs)
>> + struct pt_regs *regs,
>> + bool exclude_kernel)
>> {
>> - regs_intr->regs = regs;
>> - regs_intr->abi = perf_reg_abi(current);
>> + /*
>> + * Hardware skid can lead to PMI is delivered after
>> + * the CPU has already entered kernel mode. In that case,
> Sorry to nitpick but it might be better to say "Hardware skid can lead
> to a scenario where a PMI is delivered..."
Sure. Thanks.
>
> Other than that, LGTM.
>
> Reviewed-by: Thomas Falcon <thomas.falcon@xxxxxxxxx>
>
> Thanks,
> Tom
>
>> + * user-space sampling must not expose kernel register
>> state.
>> + */
>> + if (exclude_kernel && !user_mode(regs)) {
>> + regs_intr->abi = PERF_SAMPLE_REGS_ABI_NONE;
>> + regs_intr->regs = NULL;
>> + } else {
>> + regs_intr->regs = regs;
>> + regs_intr->abi = perf_reg_abi(current);
>> + }
>> }
>>
>>
>> @@ -8694,7 +8705,8 @@ void perf_prepare_sample(struct
>> perf_sample_data *data,
>> /* regs dump ABI info */
>> int size = sizeof(u64);
>>
>> - perf_sample_regs_intr(&data->regs_intr, regs);
>> + perf_sample_regs_intr(&data->regs_intr, regs,
>> + event->attr.exclude_kernel);
>>
>> if (data->regs_intr.regs) {
>> u64 mask = event->attr.sample_regs_intr;