• Mark Rutland's avatar
    arm64: prevent instrumentation of bp hardening callbacks · 614c0b9f
    Mark Rutland authored
    We may call arm64_apply_bp_hardening() early during entry (e.g. in
    el0_ia()) before it is safe to run instrumented code. Unfortunately this
    may result in running instrumented code in two cases:
    
    * The hardening callbacks called by arm64_apply_bp_hardening() are not
      marked as `noinstr`, and have been observed to be instrumented when
      compiled with either GCC or LLVM.
    
    * Since arm64_apply_bp_hardening() itself is only marked as `inline`
      rather than `__always_inline`, it is possible that the compiler
      decides to place it out-of-line, whereupon it may be instrumented.
    
    For example, with defconfig built with clang 13.0.0,
    call_hvc_arch_workaround_1() is compiled as:
    
    | <call_hvc_arch_workaround_1>:
    |        d503233f        paciasp
    |        f81f0ffe        str     x30, [sp, #-16]!
    |        320183e0        mov     w0, #0x80008000
    |        d503201f        nop
    |        d4000002        hvc     #0x0
    |        f84107fe        ldr     x30, [sp], #16
    |        d50323bf        autiasp
    |        d65f03c0        ret
    
    ... but when CONFIG_FTRACE=y and CONFIG_KCOV=y this is compiled as:
    
    | <call_hvc_arch_workaround_1>:
    |        d503245f        bti     c
    |        d503201f        nop
    |        d503201f        nop
    |        d503233f        paciasp
    |        a9bf7bfd        stp     x29, x30, [sp, #-16]!
    |        910003fd        mov     x29, sp
    |        94000000        bl      0 <__sanitizer_cov_trace_pc>
    |        320183e0        mov     w0, #0x80008000
    |        d503201f        nop
    |        d4000002        hvc     #0x0
    |        a8c17bfd        ldp     x29, x30, [sp], #16
    |        d50323bf        autiasp
    |        d65f03c0        ret
    
    ... with a patchable function entry registered with ftrace, and a direct
    call to __sanitizer_cov_trace_pc(). Neither of these are safe early
    during entry sequences.
    
    This patch avoids the unsafe instrumentation by marking
    arm64_apply_bp_hardening() as `__always_inline` and by marking the
    hardening functions as `noinstr`. This avoids the potential for
    instrumentation, and causes clang to consistently generate the function
    as with the defconfig sample.
    
    Note: in the defconfig compilation, when CONFIG_SVE=y, x30 is spilled to
    the stack without being placed in a frame record, which will result in a
    missing entry if call_hvc_arch_workaround_1() is backtraced. Similar is
    true of qcom_link_stack_sanitisation(), where inline asm spills the LR
    to a GPR prior to corrupting it. This is not a significant issue
    presently as we will only backtrace here if an exception is taken, and
    in such cases we may omit entries for other reasons today.
    
    The relevant hardening functions were introduced in commits:
    
      ec82b567 ("arm64: Implement branch predictor hardening for Falkor")
      b092201e ("arm64: Add ARM_SMCCC_ARCH_WORKAROUND_1 BP hardening support")
    
    ... and these were subsequently moved in commit:
    
      d4647f0a ("arm64: Rewrite Spectre-v2 mitigation code")
    
    The arm64_apply_bp_hardening() function was introduced in commit:
    
      0f15adbb ("arm64: Add skeleton to harden the branch predictor against aliasing attacks")
    
    ... and was subsequently moved and reworked in commit:
    
      6279017e ("KVM: arm64: Move BP hardening helpers into spectre.h")
    
    Fixes: ec82b567 ("arm64: Implement branch predictor hardening for Falkor")
    Fixes: b092201e ("arm64: Add ARM_SMCCC_ARCH_WORKAROUND_1 BP hardening support")
    Fixes: d4647f0a ("arm64: Rewrite Spectre-v2 mitigation code")
    Fixes: 0f15adbb ("arm64: Add skeleton to harden the branch predictor against aliasing attacks")
    Fixes: 6279017e ("KVM: arm64: Move BP hardening helpers into spectre.h")
    Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
    Cc: Ard Biesheuvel <ardb@kernel.org>
    Cc: Catalin Marinas <catalin.marinas@arm.com>
    Cc: James Morse <james.morse@arm.com>
    Cc: Marc Zyngier <maz@kernel.org>
    Cc: Mark Brown <broonie@kernel.org>
    Cc: Will Deacon <will@kernel.org>
    Acked-by: default avatarMarc Zyngier <maz@kernel.org>
    Reviewed-by: default avatarMark Brown <broonie@kernel.org>
    Link: https://lore.kernel.org/r/20220224181028.512873-1-mark.rutland@arm.comSigned-off-by: default avatarWill Deacon <will@kernel.org>
    614c0b9f
spectre.h 2.53 KB