Re: [tip: x86/bugs] x86/retpoline: Ensure default return thunk isn't used at runtime

From: Borislav Petkov
Date: Thu Feb 15 2024 - 10:54:13 EST


On Wed, Feb 14, 2024 at 08:20:49PM -0700, Nathan Chancellor wrote:
> On Mon, Feb 12, 2024 at 02:13:39PM -0000, tip-bot2 for Josh Poimboeuf wrote:
> > The following commit has been merged into the x86/bugs branch of tip:
> >
> > Commit-ID: 4461438a8405e800f90e0e40409e5f3d07eed381
> > Gitweb: https://git.kernel.org/tip/4461438a8405e800f90e0e40409e5f3d07eed381
> > Author: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
> > AuthorDate: Wed, 03 Jan 2024 19:36:26 +01:00
> > Committer: Borislav Petkov (AMD) <bp@xxxxxxxxx>
> > CommitterDate: Mon, 12 Feb 2024 11:42:15 +01:00
> >
> > x86/retpoline: Ensure default return thunk isn't used at runtime
> >
> > Make sure the default return thunk is not used after all return
> > instructions have been patched by the alternatives because the default
> > return thunk is insufficient when it comes to mitigating Retbleed or
> > SRSO.
> >
> > Fix based on an earlier version by David Kaplan <david.kaplan@xxxxxxx>.
> >
> > [ bp: Fix the compilation error of warn_thunk_thunk being an invisible
> > symbol, hoist thunk macro into calling.h ]
> >
> > Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
> > Co-developed-by: Borislav Petkov (AMD) <bp@xxxxxxxxx>
> > Signed-off-by: Borislav Petkov (AMD) <bp@xxxxxxxxx>
> > Link: https://lore.kernel.org/r/20231010171020.462211-4-david.kaplan@xxxxxxx
> > Link: https://lore.kernel.org/r/20240104132446.GEZZaxnrIgIyat0pqf@fat_crate.local
>
> This warning is now getting triggered for me in some of my builds,
> specifically from Alpine Linux's configuration. A minimal reproducer on
> top of defconfig:
>
> $ echo 'CONFIG_X86_KERNEL_IBT=n
> CONFIG_UNWINDER_ORC=n
> CONFIG_UNWINDER_FRAME_POINTER=y' >arch/x86/configs/repro.config

Yeah, the special vdso glue:

[ 325.985728] PCI: Using configuration type 1 for base access
[ 325.986637] PCI: Using configuration type 1 for extended access
[ 325.987797] initcall pci_arch_init+0x0/0x90 returned 0 after 3000 usecs
[ 325.988815] calling init_vdso_image_64+0x0/0x30 @ 1
[ 325.989804] ------------[ cut here ]------------
[ 325.990724] Unpatched return thunk in use. This should not happen!
[ 325.991735] WARNING: CPU: 0 PID: 1 at arch/x86/kernel/cpu/bugs.c:2856 __warn_thunk+0x27/0x40
[ 325.992793] Modules linked in:
[ 325.993440] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.8.0-rc4-00040-g4589f199eb68 #1
[ 325.993794] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[ 325.994794] RIP: 0010:__warn_thunk+0x27/0x40
[ 325.995648] Code: 90 90 90 80 3d 62 38 c3 01 00 74 05 e9 52 07 ee 00 55 c6 05 53 38 c3 01 01 48 89 e5 90 48 c7 c7 08 54 71 82 e8 9a c9 03 00 90 <0f> 0b 90 90 5d e9 2f 07 ee 00 cc cc cc cc cc cc cc cc cc cc cc cc
[ 325.996793] RSP: 0018:ffffc90000013e10 EFLAGS: 00010286
[ 325.997793] RAX: 0000000000000000 RBX: ffffffff82cfdac0 RCX: 0000000000000000
[ 325.998795] RDX: 0000000000000000 RSI: 00000000fff7ffff RDI: 0000000000000001
[ 325.999793] RBP: ffffc90000013e10 R08: 00000000fff7ffff R09: ffffc90000013c90
[ 326.000794] R10: 0000000000000001 R11: ffff88807b7df000 R12: 0000000000000000
[ 326.001793] R13: ffff8880035f9900 R14: ffffc90000013e78 R15: 0000000000000000
[ 326.002795] FS: 0000000000000000(0000) GS:ffff888079200000(0000) knlGS:0000000000000000
[ 326.003795] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 326.004793] CR2: ffff888003201000 CR3: 0000000002a2c000 CR4: 00000000003506f0
[ 326.005794] Call Trace:
[ 326.006339] <TASK>
[ 326.006794] ? show_regs+0x5f/0x70
[ 326.007501] ? __warn+0x83/0x130
[ 326.007794] ? __warn_thunk+0x27/0x40
[ 326.008542] ? report_bug+0x171/0x1a0
[ 326.008793] ? srso_return_thunk+0x5/0x5f
[ 326.009603] ? console_unlock+0x4f/0xe0
[ 326.010381] ? handle_bug+0x43/0x80
[ 326.010795] ? exc_invalid_op+0x18/0x70
[ 326.011592] ? asm_exc_invalid_op+0x1b/0x20
[ 326.012440] ? ia32_binfmt_init+0x40/0x40
[ 326.012795] ? __warn_thunk+0x27/0x40
[ 326.013546] warn_thunk_thunk+0x16/0x30
[ 326.013795] do_one_initcall+0x59/0x230
[ 326.014574] kernel_init_freeable+0x19a/0x2d0
[ 326.014794] ? __pfx_kernel_init+0x10/0x10
[ 326.015629] kernel_init+0x15/0x1b0
[ 326.016326] ret_from_fork+0x38/0x60
[ 326.016794] ? __pfx_kernel_init+0x10/0x10
[ 326.017627] ret_from_fork_asm+0x1a/0x30
[ 326.018394] </TASK>
[ 326.018794] ---[ end trace 0000000000000000 ]---
[ 326.019705] initcall init_vdso_image_64+0x0/0x30 returned 0 after 29000 usecs
[ 326.020794] calling init_vdso_image_32+0x0/0x20 @ 1

During build we do:

# VDSO2C arch/x86/entry/vdso/vdso-image-64.c
arch/x86/entry/vdso/vdso2c arch/x86/entry/vdso/vdso64.so.dbg arch/x86/entry/vdso/vdso64.so arch/x86/entry/vdso/vdso-image-64.c

...

# CC arch/x86/entry/vdso/vdso-image-64.o
gcc -Wp,-MMD,arch/x86/entry/vdso/.vdso-image-64.o.d -nostdinc -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/compiler-version.h -include ./include/linux/kconfig.h -include ./include/linux/compiler_types.h -D__KERNEL__ -fmacro-prefix-map=./= -Werror -std=gnu11 -fshort-wchar -funsigned-char -fno-common -fno-PIE -fno-strict-aliasing -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -fcf-protection=none -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -mindirect-branch-cs-prefix -mfunction-return=thunk-extern -fno-jump-tables -fpatchable-function-entry=16,16 -fno-delete-null-pointer-checks -O2 -fno-allow-store-data-races -fstack-protector-strong -fno-omit-frame-pointer -fno-optimize-sibling-calls -ftrivial-auto-var-init=zero -fno-stack-clash-protection -falign-functions=16 -fstrict-flex-arrays=3 -fno-strict-overflow -fno-stack-check -fconserve-stack -Wall -Wundef -Werror=implicit-function-declaration -Werror=implicit-int -Werror=return-type -Werror=strict-prototypes -Wno-format-security -Wno-trigraphs -Wno-frame-address -Wno-address-of-packed-member -Wmissing-declarations -Wmissing-prototypes -Wframe-larger-than=2048 -Wno-main -Wno-unused-but-set-variable -Wno-unused-const-variable -Wno-dangling-pointer -Wvla -Wno-pointer-sign -Wcast-function-type -Wno-stringop-overflow -Wno-array-bounds -Wno-alloc-size-larger-than -Wimplicit-fallthrough=5 -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -Wenum-conversion -Wno-unused-but-set-variable -Wno-unused-const-variable -Wno-restrict -Wno-packed-not-aligned -Wno-format-overflow -Wno-format-truncation -Wno-stringop-truncation -Wno-missing-field-initializers -Wno-type-limits -Wno-shift-negative-value -Wno-maybe-uninitialized -Wno-sign-compare -DKBUILD_MODFILE='"arch/x86/entry/vdso/vdso-image-64"' -DKBUILD_BASENAME='"vdso_image_64"' -DKBUILD_MODNAME='"vdso_image_64"' -D__KBUILD_MODNAME=kmod_vdso_image_64 -c -o arch/x86/entry/vdso/vdso-image-64.o arch/x86/entry/vdso/vdso-image-64.c

...

and what is missing here is

# cmd_gen_objtooldep arch/x86/lib/vdso-image-64.o
{ echo ; echo 'arch/x86/lib/vdso-image-64.o: $(wildcard ./tools/objtool/objtool)' ; } >> arch/x86/lib/...

or so which needs to create the .return_sites but that thing gets
generated without it:

rm -f arch/x86/entry/vdso/built-in.a; printf "arch/x86/entry/vdso/%s " vma.o extable.o vdso32-setup.o vdso-image-64.o vdso-image-32.o | xargs ar cDPrST arch/x86/entry/vdso/built-in.a

I'd tend to look in Josh's direction as to say what would be the right
thing to do here and more specifically, where?

We need to run objtool on the vdso objects which are *kernel* code.
I.e., that initcall thing. The vdso-image-64.c gets generated by vdso2c
and lands in arch/x86/entry/vdso/vdso-image-64.c, that's why objtool
hasn't seen it yet.

I mean, it is one initcall in the vdso, probably not that important and
if its return hasn't been patched, it won't be the end of the world but
still...

In any case, the patch works as advertized! :-)

Thx.

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette