• Josh Poimboeuf's avatar
    x86/speculation: Prepare entry code for Spectre v1 swapgs mitigations · 4b0c9c8a
    Josh Poimboeuf authored
    Spectre v1 isn't only about array bounds checks.  It can affect any
    conditional checks.  The kernel entry code interrupt, exception, and NMI
    handlers all have conditional swapgs checks.  Those may be problematic in
    the context of Spectre v1, as kernel code can speculatively run with a user
    GS.
    
    For example:
    
    	if (coming from user space)
    		swapgs
    	mov %gs:<percpu_offset>, %reg
    	mov (%reg), %reg1
    
    When coming from user space, the CPU can speculatively skip the swapgs, and
    then do a speculative percpu load using the user GS value.  So the user can
    speculatively force a read of any kernel value.  If a gadget exists which
    uses the percpu value as an address in another load/store, then the
    contents of the kernel value may become visible via an L1 side channel
    attack.
    
    A similar attack exists when coming from kernel space.  The CPU can
    speculatively do the swapgs, causing the user GS to get used for the rest
    of the speculative window.
    
    The mitigation is similar to a traditional Spectre v1 mitigation, except:
    
      a) index masking isn't possible; because the index (percpu offset)
         isn't user-controlled; and
    
      b) an lfence is needed in both the "from user" swapgs path and the
         "from kernel" non-swapgs path (because of the two attacks described
         above).
    
    The user entry swapgs paths already have SWITCH_TO_KERNEL_CR3, which has a
    CR3 write when PTI is enabled.  Since CR3 writes are serializing, the
    lfences can be skipped in those cases.
    
    On the other hand, the kernel entry swapgs paths don't depend on PTI.
    
    To avoid unnecessary lfences for the user entry case, create two separate
    features for alternative patching:
    
      X86_FEATURE_FENCE_SWAPGS_USER
      X86_FEATURE_FENCE_SWAPGS_KERNEL
    
    Use these features in entry code to patch in lfences where needed.
    
    The features aren't enabled yet, so there's no functional change.
    Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Reviewed-by: default avatarDave Hansen <dave.hansen@intel.com>
    
    CVE-2019-1125
    
    (backported from commit 18ec54fd)
    [tyhicks: Backport to Xenial:
     - Adjust context in calling.h
     - Minor rework of fencing in entry_64.S due to differences in entry points
     - Add a FENCE_SWAPGS_KERNEL_ENTRY to a swapgs, in NMI entry path, that
       wasn't present in newer kernels
     - Indent macros in calling.h to match the rest of the file's style
     - Move include of calling.h later in entry_64.S to fix build failure]
    Signed-off-by: default avatarTyler Hicks <tyhicks@canonical.com>
    Signed-off-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
    4b0c9c8a
calling.h 6.81 KB