lkml.org 
[lkml]   [2024]   [Feb]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] x86/vdso: Fix rethunk patching for vdso-image-{32,64}.o
    For CONFIG_RETHUNK kernels, objtool annotates all the function return
    sites so they can be patched during boot. By design, after
    apply_returns() is called, all tail-calls to the compiler-generated
    default return thunk (__x86_return_thunk) should be patched out and
    replaced with whatever's needed for any mitigations (or lack thereof).

    With the following commit

    4461438a8405 ("x86/retpoline: Ensure default return thunk isn't used at runtime")

    a runtime check was added to do a WARN_ONCE() if the default return
    thunk ever gets executed after alternatives have been applied. This
    warning is a sanity check to make sure objtool and apply_returns() are
    doing their job.

    As Nathan reported, that check found something:

    Unpatched return thunk in use. This should not happen!
    WARNING: CPU: 0 PID: 1 at arch/x86/kernel/cpu/bugs.c:2856 __warn_thunk+0x27/0x40
    Modules linked in:
    CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.7.0-01738-g4461438a8405-dirty #1
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
    RIP: 0010:__warn_thunk+0x27/0x40
    Code: 90 90 90 80 3d 22 20 c3 01 00 74 05 e9 32 a5 eb 00 55 c6 05 13 20 c3 01 01 48 89 e5 90 48 c7 c7 80 80 50 89 e8 6a c4 03 00 90 <0f> 0b 90 90 5d e9 0f a5 eb 00 cc cc cc cc cc cc cc cc cc cc cc cc
    RSP: 0018:ffff8ba9c0013e10 EFLAGS: 00010286
    RAX: 0000000000000000 RBX: ffffffff89afba70 RCX: 0000000000000000
    RDX: 0000000000000000 RSI: 00000000ffffdfff RDI: 0000000000000001
    RBP: ffff8ba9c0013e10 R08: 00000000ffffdfff R09: ffff8ba9c0013c88
    R10: 0000000000000001 R11: ffffffff89856ae0 R12: 0000000000000000
    R13: ffff88c101126ac0 R14: ffff8ba9c0013e78 R15: 0000000000000000
    FS: 0000000000000000(0000) GS:ffff88c11f000000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: ffff88c119601000 CR3: 0000000018e2c000 CR4: 0000000000350ef0
    Call Trace:
    <TASK>
    ? show_regs+0x60/0x70
    ? __warn+0x84/0x150
    ? __warn_thunk+0x27/0x40
    ? report_bug+0x16d/0x1a0
    ? console_unlock+0x4f/0xe0
    ? handle_bug+0x43/0x80
    ? exc_invalid_op+0x18/0x70
    ? asm_exc_invalid_op+0x1b/0x20
    ? ia32_binfmt_init+0x40/0x40
    ? __warn_thunk+0x27/0x40
    warn_thunk_thunk+0x16/0x30
    do_one_initcall+0x59/0x230
    kernel_init_freeable+0x1a4/0x2e0
    ? __pfx_kernel_init+0x10/0x10
    kernel_init+0x15/0x1b0
    ret_from_fork+0x38/0x60
    ? __pfx_kernel_init+0x10/0x10
    ret_from_fork_asm+0x1b/0x30
    </TASK>

    Boris debugged to find that the unpatched return site was in
    init_vdso_image_64(), and its translation unit wasn't being analyzed by
    objtool, so it never got annotated. So it got ignored by
    apply_returns().

    This is only a minor issue, as this function is only called during boot.
    Still, objtool needs full visibility to the kernel. Fix it by enabling
    objtool on vdso-image-{32,64}.o.

    Note this problem can only be seen with !CONFIG_X86_KERNEL_IBT, as that
    requires objtool to run individually on all translation units rather on
    vmlinux.o.

    Reported-by: Nathan Chancellor <nathan@kernel.org>
    Debugged-by: Borislav Petkov <bp@alien8.de>
    Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
    ---
    arch/x86/entry/vdso/Makefile | 9 ++++++---
    1 file changed, 6 insertions(+), 3 deletions(-)

    diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
    index b1b8dd1608f7..4ee59121b905 100644
    --- a/arch/x86/entry/vdso/Makefile
    +++ b/arch/x86/entry/vdso/Makefile
    @@ -34,8 +34,12 @@ obj-y += vma.o extable.o
    KASAN_SANITIZE_vma.o := y
    UBSAN_SANITIZE_vma.o := y
    KCSAN_SANITIZE_vma.o := y
    -OBJECT_FILES_NON_STANDARD_vma.o := n
    -OBJECT_FILES_NON_STANDARD_extable.o := n
    +
    +OBJECT_FILES_NON_STANDARD_extable.o := n
    +OBJECT_FILES_NON_STANDARD_vdso-image-32.o := n
    +OBJECT_FILES_NON_STANDARD_vdso-image-64.o := n
    +OBJECT_FILES_NON_STANDARD_vdso32-setup.o := n
    +OBJECT_FILES_NON_STANDARD_vma.o := n

    # vDSO images to build
    vdso_img-$(VDSO64-y) += 64
    @@ -43,7 +47,6 @@ vdso_img-$(VDSOX32-y) += x32
    vdso_img-$(VDSO32-y) += 32

    obj-$(VDSO32-y) += vdso32-setup.o
    -OBJECT_FILES_NON_STANDARD_vdso32-setup.o := n

    vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)
    vobjs32 := $(foreach F,$(vobjs32-y),$(obj)/$F)
    --
    2.43.0

    \
     
     \ /
      Last update: 2024-05-27 15:11    [W:6.003 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site