• Josh Poimboeuf's avatar
    x86/speculation: Enable Spectre v1 swapgs mitigations · a2059825
    Josh Poimboeuf authored
    
    The previous commit added macro calls in the entry code which mitigate the
    Spectre v1 swapgs issue if the X86_FEATURE_FENCE_SWAPGS_* features are
    enabled.  Enable those features where applicable.
    
    The mitigations may be disabled with "nospectre_v1" or "mitigations=off".
    
    There are different features which can affect the risk of attack:
    
    - When FSGSBASE is enabled, unprivileged users are able to place any
      value in GS, using the wrgsbase instruction.  This means they can
      write a GS value which points to any value in kernel space, which can
      be useful with the following gadget in an interrupt/exception/NMI
      handler:
    
    	if (coming from user space)
    		swapgs
    	mov %gs:<percpu_offset>, %reg1
    	// dependent load or store based on the value of %reg
    	// for example: mov %(reg1), %reg2
    
      If an interrupt is coming from user space, and the entry code
      speculatively skips the swapgs (due to user branch mistraining), it
      may speculatively execute the GS-based load and a subsequent dependent
      load or store, exposing the kernel data to an L1 side channel leak.
    
      Note that, on Intel, a similar attack exists in the above gadget when
      coming from kernel space, if the swapgs gets speculatively executed to
      switch back to the user GS.  On AMD, this variant isn't possible
      because swapgs is serializing with respect to future GS-based
      accesses.
    
      NOTE: The FSGSBASE patch set hasn't been merged yet, so the above case
    	doesn't exist quite yet.
    
    - When FSGSBASE is disabled, the issue is mitigated somewhat because
      unprivileged users must use prctl(ARCH_SET_GS) to set GS, which
      restricts GS values to user space addresses only.  That means the
      gadget would need an additional step, since the target kernel address
      needs to be read from user space first.  Something like:
    
    	if (coming from user space)
    		swapgs
    	mov %gs:<percpu_offset>, %reg1
    	mov (%reg1), %reg2
    	// dependent load or store based on the value of %reg2
    	// for example: mov %(reg2), %reg3
    
      It's difficult to audit for this gadget in all the handlers, so while
      there are no known instances of it, it's entirely possible that it
      exists somewhere (or could be introduced in the future).  Without
      tooling to analyze all such code paths, consider it vulnerable.
    
      Effects of SMAP on the !FSGSBASE case:
    
      - If SMAP is enabled, and the CPU reports RDCL_NO (i.e., not
        susceptible to Meltdown), the kernel is prevented from speculatively
        reading user space memory, even L1 cached values.  This effectively
        disables the !FSGSBASE attack vector.
    
      - If SMAP is enabled, but the CPU *is* susceptible to Meltdown, SMAP
        still prevents the kernel from speculatively reading user space
        memory.  But it does *not* prevent the kernel from reading the
        user value from L1, if it has already been cached.  This is probably
        only a small hurdle for an attacker to overcome.
    
    Thanks to Dave Hansen for contributing the speculative_smap() function.
    
    Thanks to Andrew Cooper for providing the inside scoop on whether swapgs
    is serializing on AMD.
    
    [ tglx: Fixed the USER fence decision and polished the comment as suggested
      	by Dave Hansen ]
    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>
    a2059825
bugs.c 40.7 KB