Skip to content

Commit e583bff

Browse files
committed
Merge tag 'x86-urgent-2023-09-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull misc x86 fixes from Ingo Molnar: - Fix a kexec bug - Fix an UML build bug - Fix a handful of SRSO related bugs - Fix a shadow stacks handling bug & robustify related code * tag 'x86-urgent-2023-09-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/shstk: Add warning for shadow stack double unmap x86/shstk: Remove useless clone error handling x86/shstk: Handle vfork clone failure correctly x86/srso: Fix SBPB enablement for spec_rstack_overflow=off x86/srso: Don't probe microcode in a guest x86/srso: Set CPUID feature bits independently of bug or mitigation status x86/srso: Fix srso_show_state() side effect x86/asm: Fix build of UML with KASAN x86/mm, kexec, ima: Use memblock_free_late() from ima_free_kexec_buffer()
2 parents 5b47b57 + 509ff51 commit e583bff

File tree

11 files changed

+56
-55
lines changed

11 files changed

+56
-55
lines changed

arch/x86/include/asm/linkage.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@
105105
CFI_POST_PADDING \
106106
SYM_FUNC_END(__cfi_##name)
107107

108+
/* UML needs to be able to override memcpy() and friends for KASAN. */
109+
#ifdef CONFIG_UML
110+
# define SYM_FUNC_ALIAS_MEMFUNC SYM_FUNC_ALIAS_WEAK
111+
#else
112+
# define SYM_FUNC_ALIAS_MEMFUNC SYM_FUNC_ALIAS
113+
#endif
114+
108115
/* SYM_TYPED_FUNC_START -- use for indirectly called globals, w/ CFI type */
109116
#define SYM_TYPED_FUNC_START(name) \
110117
SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_F_ALIGN) \

arch/x86/include/asm/mmu_context.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,7 @@ do { \
186186
#else
187187
#define deactivate_mm(tsk, mm) \
188188
do { \
189-
if (!tsk->vfork_done) \
190-
shstk_free(tsk); \
189+
shstk_free(tsk); \
191190
load_gs_index(0); \
192191
loadsegment(fs, 0); \
193192
} while (0)

arch/x86/include/asm/processor.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -683,13 +683,11 @@ extern u16 get_llc_id(unsigned int cpu);
683683
#ifdef CONFIG_CPU_SUP_AMD
684684
extern u32 amd_get_nodes_per_socket(void);
685685
extern u32 amd_get_highest_perf(void);
686-
extern bool cpu_has_ibpb_brtype_microcode(void);
687686
extern void amd_clear_divider(void);
688687
extern void amd_check_microcode(void);
689688
#else
690689
static inline u32 amd_get_nodes_per_socket(void) { return 0; }
691690
static inline u32 amd_get_highest_perf(void) { return 0; }
692-
static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; }
693691
static inline void amd_clear_divider(void) { }
694692
static inline void amd_check_microcode(void) { }
695693
#endif

arch/x86/kernel/cpu/amd.c

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,15 @@ static void early_init_amd(struct cpuinfo_x86 *c)
766766

767767
if (cpu_has(c, X86_FEATURE_TOPOEXT))
768768
smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1;
769+
770+
if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && !cpu_has(c, X86_FEATURE_IBPB_BRTYPE)) {
771+
if (c->x86 == 0x17 && boot_cpu_has(X86_FEATURE_AMD_IBPB))
772+
setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE);
773+
else if (c->x86 >= 0x19 && !wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) {
774+
setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE);
775+
setup_force_cpu_cap(X86_FEATURE_SBPB);
776+
}
777+
}
769778
}
770779

771780
static void init_amd_k8(struct cpuinfo_x86 *c)
@@ -1301,25 +1310,6 @@ void amd_check_microcode(void)
13011310
on_each_cpu(zenbleed_check_cpu, NULL, 1);
13021311
}
13031312

1304-
bool cpu_has_ibpb_brtype_microcode(void)
1305-
{
1306-
switch (boot_cpu_data.x86) {
1307-
/* Zen1/2 IBPB flushes branch type predictions too. */
1308-
case 0x17:
1309-
return boot_cpu_has(X86_FEATURE_AMD_IBPB);
1310-
case 0x19:
1311-
/* Poke the MSR bit on Zen3/4 to check its presence. */
1312-
if (!wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) {
1313-
setup_force_cpu_cap(X86_FEATURE_SBPB);
1314-
return true;
1315-
} else {
1316-
return false;
1317-
}
1318-
default:
1319-
return false;
1320-
}
1321-
}
1322-
13231313
/*
13241314
* Issue a DIV 0/1 insn to clear any division data from previous DIV
13251315
* operations.

arch/x86/kernel/cpu/bugs.c

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,26 +2404,15 @@ early_param("spec_rstack_overflow", srso_parse_cmdline);
24042404

24052405
static void __init srso_select_mitigation(void)
24062406
{
2407-
bool has_microcode;
2407+
bool has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE);
24082408

24092409
if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off())
24102410
goto pred_cmd;
24112411

2412-
/*
2413-
* The first check is for the kernel running as a guest in order
2414-
* for guests to verify whether IBPB is a viable mitigation.
2415-
*/
2416-
has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) || cpu_has_ibpb_brtype_microcode();
24172412
if (!has_microcode) {
24182413
pr_warn("IBPB-extending microcode not applied!\n");
24192414
pr_warn(SRSO_NOTICE);
24202415
} else {
2421-
/*
2422-
* Enable the synthetic (even if in a real CPUID leaf)
2423-
* flags for guests.
2424-
*/
2425-
setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE);
2426-
24272416
/*
24282417
* Zen1/2 with SMT off aren't vulnerable after the right
24292418
* IBPB microcode has been applied.
@@ -2444,7 +2433,7 @@ static void __init srso_select_mitigation(void)
24442433

24452434
switch (srso_cmd) {
24462435
case SRSO_CMD_OFF:
2447-
return;
2436+
goto pred_cmd;
24482437

24492438
case SRSO_CMD_MICROCODE:
24502439
if (has_microcode) {
@@ -2717,7 +2706,7 @@ static ssize_t srso_show_state(char *buf)
27172706

27182707
return sysfs_emit(buf, "%s%s\n",
27192708
srso_strings[srso_mitigation],
2720-
(cpu_has_ibpb_brtype_microcode() ? "" : ", no microcode"));
2709+
boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode");
27212710
}
27222711

27232712
static ssize_t gds_show_state(char *buf)

arch/x86/kernel/process.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
257257
if (!ret && unlikely(test_tsk_thread_flag(current, TIF_IO_BITMAP)))
258258
io_bitmap_share(p);
259259

260-
/*
261-
* If copy_thread() if failing, don't leak the shadow stack possibly
262-
* allocated in shstk_alloc_thread_stack() above.
263-
*/
264-
if (ret)
265-
shstk_free(p);
266-
267260
return ret;
268261
}
269262

arch/x86/kernel/setup.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -358,15 +358,11 @@ static void __init add_early_ima_buffer(u64 phys_addr)
358358
#if defined(CONFIG_HAVE_IMA_KEXEC) && !defined(CONFIG_OF_FLATTREE)
359359
int __init ima_free_kexec_buffer(void)
360360
{
361-
int rc;
362-
363361
if (!ima_kexec_buffer_size)
364362
return -ENOENT;
365363

366-
rc = memblock_phys_free(ima_kexec_buffer_phys,
367-
ima_kexec_buffer_size);
368-
if (rc)
369-
return rc;
364+
memblock_free_late(ima_kexec_buffer_phys,
365+
ima_kexec_buffer_size);
370366

371367
ima_kexec_buffer_phys = 0;
372368
ima_kexec_buffer_size = 0;

arch/x86/kernel/shstk.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,21 @@ unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, unsigned long cl
205205
return 0;
206206

207207
/*
208-
* For CLONE_VM, except vfork, the child needs a separate shadow
208+
* For CLONE_VFORK the child will share the parents shadow stack.
209+
* Make sure to clear the internal tracking of the thread shadow
210+
* stack so the freeing logic run for child knows to leave it alone.
211+
*/
212+
if (clone_flags & CLONE_VFORK) {
213+
shstk->base = 0;
214+
shstk->size = 0;
215+
return 0;
216+
}
217+
218+
/*
219+
* For !CLONE_VM the child will use a copy of the parents shadow
209220
* stack.
210221
*/
211-
if ((clone_flags & (CLONE_VFORK | CLONE_VM)) != CLONE_VM)
222+
if (!(clone_flags & CLONE_VM))
212223
return 0;
213224

214225
size = adjust_shstk_size(stack_size);
@@ -408,7 +419,25 @@ void shstk_free(struct task_struct *tsk)
408419
if (!tsk->mm || tsk->mm != current->mm)
409420
return;
410421

422+
/*
423+
* If shstk->base is NULL, then this task is not managing its
424+
* own shadow stack (CLONE_VFORK). So skip freeing it.
425+
*/
426+
if (!shstk->base)
427+
return;
428+
429+
/*
430+
* shstk->base is NULL for CLONE_VFORK child tasks, and so is
431+
* normal. But size = 0 on a shstk->base is not normal and
432+
* indicated an attempt to free the thread shadow stack twice.
433+
* Warn about it.
434+
*/
435+
if (WARN_ON(!shstk->size))
436+
return;
437+
411438
unmap_shadow_stack(shstk->base, shstk->size);
439+
440+
shstk->size = 0;
412441
}
413442

414443
static int wrss_control(bool enable)

arch/x86/lib/memcpy_64.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ SYM_TYPED_FUNC_START(__memcpy)
4040
SYM_FUNC_END(__memcpy)
4141
EXPORT_SYMBOL(__memcpy)
4242

43-
SYM_FUNC_ALIAS(memcpy, __memcpy)
43+
SYM_FUNC_ALIAS_MEMFUNC(memcpy, __memcpy)
4444
EXPORT_SYMBOL(memcpy)
4545

4646
SYM_FUNC_START_LOCAL(memcpy_orig)

arch/x86/lib/memmove_64.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,5 +212,5 @@ SYM_FUNC_START(__memmove)
212212
SYM_FUNC_END(__memmove)
213213
EXPORT_SYMBOL(__memmove)
214214

215-
SYM_FUNC_ALIAS(memmove, __memmove)
215+
SYM_FUNC_ALIAS_MEMFUNC(memmove, __memmove)
216216
EXPORT_SYMBOL(memmove)

arch/x86/lib/memset_64.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ SYM_FUNC_START(__memset)
4040
SYM_FUNC_END(__memset)
4141
EXPORT_SYMBOL(__memset)
4242

43-
SYM_FUNC_ALIAS(memset, __memset)
43+
SYM_FUNC_ALIAS_MEMFUNC(memset, __memset)
4444
EXPORT_SYMBOL(memset)
4545

4646
SYM_FUNC_START_LOCAL(memset_orig)

0 commit comments

Comments
 (0)