Skip to content

Commit 87fa732

Browse files
committed
Merge tag 'x86-core-2023-08-30-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 core updates from Thomas Gleixner: - Prevent kprobes on compiler generated CFI checking code. The compiler generates an instruction sequence for indirect call checks. If this sequence is modified with a kprobe, then the check fails. So the instructions must be protected against probing. - A few minor cleanups for the SMP code * tag 'x86-core-2023-08-30-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/kprobes: Prohibit probing on compiler generated CFI checking code x86/smpboot: Change smp_store_boot_cpu_info() to static x86/smp: Remove a non-existent function declaration x86/smpboot: Remove a stray comment about CPU hotplug
2 parents 9855922 + b654137 commit 87fa732

File tree

4 files changed

+39
-8
lines changed

4 files changed

+39
-8
lines changed

arch/x86/include/asm/smp.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,8 @@ void smp_kick_mwait_play_dead(void);
132132
void native_smp_send_reschedule(int cpu);
133133
void native_send_call_func_ipi(const struct cpumask *mask);
134134
void native_send_call_func_single_ipi(int cpu);
135-
void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle);
136135

137136
bool smp_park_other_cpus_in_init(void);
138-
139-
void smp_store_boot_cpu_info(void);
140137
void smp_store_cpu_info(int id);
141138

142139
asmlinkage __visible void smp_reboot_interrupt(void);

arch/x86/kernel/kprobes/core.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <linux/vmalloc.h>
4646
#include <linux/pgtable.h>
4747
#include <linux/set_memory.h>
48+
#include <linux/cfi.h>
4849

4950
#include <asm/text-patching.h>
5051
#include <asm/cacheflush.h>
@@ -293,7 +294,40 @@ static int can_probe(unsigned long paddr)
293294
#endif
294295
addr += insn.length;
295296
}
297+
if (IS_ENABLED(CONFIG_CFI_CLANG)) {
298+
/*
299+
* The compiler generates the following instruction sequence
300+
* for indirect call checks and cfi.c decodes this;
301+
*
302+
*  movl -<id>, %r10d ; 6 bytes
303+
* addl -4(%reg), %r10d ; 4 bytes
304+
* je .Ltmp1 ; 2 bytes
305+
* ud2 ; <- regs->ip
306+
* .Ltmp1:
307+
*
308+
* Also, these movl and addl are used for showing expected
309+
* type. So those must not be touched.
310+
*/
311+
__addr = recover_probed_instruction(buf, addr);
312+
if (!__addr)
313+
return 0;
314+
315+
if (insn_decode_kernel(&insn, (void *)__addr) < 0)
316+
return 0;
317+
318+
if (insn.opcode.value == 0xBA)
319+
offset = 12;
320+
else if (insn.opcode.value == 0x3)
321+
offset = 6;
322+
else
323+
goto out;
324+
325+
/* This movl/addl is used for decoding CFI. */
326+
if (is_cfi_trap(addr + offset))
327+
return 0;
328+
}
296329

330+
out:
297331
return (addr == paddr);
298332
}
299333

arch/x86/kernel/smpboot.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ int topology_update_die_map(unsigned int die, unsigned int cpu)
414414
return 0;
415415
}
416416

417-
void __init smp_store_boot_cpu_info(void)
417+
static void __init smp_store_boot_cpu_info(void)
418418
{
419419
int id = 0; /* CPU 0 */
420420
struct cpuinfo_x86 *c = &cpu_data(id);
@@ -1601,9 +1601,7 @@ void play_dead_common(void)
16011601
idle_task_exit();
16021602

16031603
cpuhp_ap_report_dead();
1604-
/*
1605-
* With physical CPU hotplug, we should halt the cpu
1606-
*/
1604+
16071605
local_irq_disable();
16081606
}
16091607

include/linux/cfi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ static inline enum bug_trap_type report_cfi_failure_noaddr(struct pt_regs *regs,
1919
{
2020
return report_cfi_failure(regs, addr, NULL, 0);
2121
}
22+
#endif /* CONFIG_CFI_CLANG */
2223

2324
#ifdef CONFIG_ARCH_USES_CFI_TRAPS
2425
bool is_cfi_trap(unsigned long addr);
26+
#else
27+
static inline bool is_cfi_trap(unsigned long addr) { return false; }
2528
#endif
26-
#endif /* CONFIG_CFI_CLANG */
2729

2830
#ifdef CONFIG_MODULES
2931
#ifdef CONFIG_ARCH_USES_CFI_TRAPS

0 commit comments

Comments
 (0)