diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-09-20 09:26:22 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-09-20 09:26:22 -0700 |
| commit | abb91eed948fcdabc7360d57cc3d3a7fba75db67 (patch) | |
| tree | 6d348e52b6f8bc893ab4c838d2a56e7f645e6797 | |
| parent | 2f7ff5f5479b020df69feb7493d4012685a8fc96 (diff) | |
| parent | 88aed0422f39b22406f35f1e758cea25e7bbcfb5 (diff) | |
Merge tag 'perf-urgent-2026-09-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf events fixes from Ingo Molnar:
- Fix crash when probing CS CALL instructions (Jinke Han)
- Fix NULL pointer crash during module unload (Vinay Belgaumkar)
* tag 'perf-urgent-2026-09-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf: Fix null pointer access in is_include_guest_event()
x86/kprobes: Fix crash when probing CS CALL instructions
| -rw-r--r-- | arch/x86/include/asm/text-patching.h | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/alternative.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/kprobes/core.c | 5 | ||||
| -rw-r--r-- | kernel/events/core.c | 4 |
4 files changed, 12 insertions, 7 deletions
diff --git a/arch/x86/include/asm/text-patching.h b/arch/x86/include/asm/text-patching.h index f2d142a0a862..ea09381070e8 100644 --- a/arch/x86/include/asm/text-patching.h +++ b/arch/x86/include/asm/text-patching.h @@ -164,9 +164,9 @@ unsigned long int3_emulate_pop(struct pt_regs *regs) } static __always_inline -void int3_emulate_call(struct pt_regs *regs, unsigned long func) +void int3_emulate_call(struct pt_regs *regs, unsigned long ip, unsigned long func) { - int3_emulate_push(regs, regs->ip - INT3_INSN_SIZE + CALL_INSN_SIZE); + int3_emulate_push(regs, ip); int3_emulate_jmp(regs, func); } diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 741d8767ddf8..582c6d8307d1 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -2176,6 +2176,7 @@ int3_exception_notify(struct notifier_block *self, unsigned long val, void *data unsigned long selftest = (unsigned long)&int3_selftest_asm; struct die_args *args = data; struct pt_regs *regs = args->regs; + unsigned long ip; OPTIMIZER_HIDE_VAR(selftest); @@ -2188,7 +2189,8 @@ int3_exception_notify(struct notifier_block *self, unsigned long val, void *data if (regs->ip - INT3_INSN_SIZE != selftest) return NOTIFY_DONE; - int3_emulate_call(regs, (unsigned long)&int3_selftest_callee); + ip = regs->ip - INT3_INSN_SIZE + CALL_INSN_SIZE; + int3_emulate_call(regs, ip, (unsigned long)&int3_selftest_callee); return NOTIFY_STOP; } @@ -2758,7 +2760,7 @@ noinstr int smp_text_poke_int3_handler(struct pt_regs *regs) break; case CALL_INSN_OPCODE: - int3_emulate_call(regs, (long)ip + tpl->disp); + int3_emulate_call(regs, (long)ip, (long)ip + tpl->disp); break; case JMP32_INSN_OPCODE: diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 4e5f8c1736ec..133ff20caccd 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -510,10 +510,9 @@ NOKPROBE_SYMBOL(kprobe_emulate_ret); static void kprobe_emulate_call(struct kprobe *p, struct pt_regs *regs) { - unsigned long func = regs->ip - INT3_INSN_SIZE + p->ainsn.size; + unsigned long ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size; - func += p->ainsn.rel32; - int3_emulate_call(regs, func); + int3_emulate_call(regs, ip, ip + p->ainsn.rel32); } NOKPROBE_SYMBOL(kprobe_emulate_call); diff --git a/kernel/events/core.c b/kernel/events/core.c index fe33fe15689d..db7b76d6b68a 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6350,6 +6350,9 @@ static DEFINE_MUTEX(perf_mediated_pmu_mutex); /* !exclude_guest event of PMU with PERF_PMU_CAP_MEDIATED_VPMU */ static inline bool is_include_guest_event(struct perf_event *event) { + if (!event->pmu) + return false; + if ((event->pmu->capabilities & PERF_PMU_CAP_MEDIATED_VPMU) && !event->attr.exclude_guest) return true; @@ -13002,6 +13005,7 @@ static void __pmu_detach_event(struct pmu *pmu, struct perf_event *event, exclusive_event_destroy(event); module_put(pmu->module); + mediated_pmu_unaccount_event(event); event->pmu = NULL; /* force fault instead of UAF */ } |
