lkml.org 
[lkml]   [2017]   [Nov]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 016/193] x86/entry/64: Add missing irqflags tracing to native_load_gs_index()
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Andy Lutomirski <luto@kernel.org>

    commit ca37e57bbe0cf1455ea3e84eb89ed04a132d59e1 upstream.

    Running this code with IRQs enabled (where dummy_lock is a spinlock):

    static void check_load_gs_index(void)
    {
    /* This will fail. */
    load_gs_index(0xffff);

    spin_lock(&dummy_lock);
    spin_unlock(&dummy_lock);
    }

    Will generate a lockdep warning. The issue is that the actual write
    to %gs would cause an exception with IRQs disabled, and the exception
    handler would, as an inadvertent side effect, update irqflag tracing
    to reflect the IRQs-off status. native_load_gs_index() would then
    turn IRQs back on and return with irqflag tracing still thinking that
    IRQs were off. The dummy lock-and-unlock causes lockdep to notice the
    error and warn.

    Fix it by adding the missing tracing.

    Apparently nothing did this in a context where it mattered. I haven't
    tried to find a code path that would actually exhibit the warning if
    appropriately nasty user code were running.

    I suspect that the security impact of this bug is very, very low --
    production systems don't run with lockdep enabled, and the warning is
    mostly harmless anyway.

    Found during a quick audit of the entry code to try to track down an
    unrelated bug that Ingo found in some still-in-development code.

    Signed-off-by: Andy Lutomirski <luto@kernel.org>
    Cc: Borislav Petkov <bpetkov@suse.de>
    Cc: Brian Gerst <brgerst@gmail.com>
    Cc: Dave Hansen <dave.hansen@intel.com>
    Cc: Josh Poimboeuf <jpoimboe@redhat.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Link: http://lkml.kernel.org/r/e1aeb0e6ba8dd430ec36c8a35e63b429698b4132.1511411918.git.luto@kernel.org
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/x86/entry/entry_64.S | 10 ++++++++--
    1 file changed, 8 insertions(+), 2 deletions(-)

    --- a/arch/x86/entry/entry_64.S
    +++ b/arch/x86/entry/entry_64.S
    @@ -51,15 +51,19 @@ ENTRY(native_usergs_sysret64)
    END(native_usergs_sysret64)
    #endif /* CONFIG_PARAVIRT */

    -.macro TRACE_IRQS_IRETQ
    +.macro TRACE_IRQS_FLAGS flags:req
    #ifdef CONFIG_TRACE_IRQFLAGS
    - bt $9, EFLAGS(%rsp) /* interrupts off? */
    + bt $9, \flags /* interrupts off? */
    jnc 1f
    TRACE_IRQS_ON
    1:
    #endif
    .endm

    +.macro TRACE_IRQS_IRETQ
    + TRACE_IRQS_FLAGS EFLAGS(%rsp)
    +.endm
    +
    /*
    * When dynamic function tracer is enabled it will add a breakpoint
    * to all locations that it is about to modify, sync CPUs, update
    @@ -923,11 +927,13 @@ ENTRY(native_load_gs_index)
    FRAME_BEGIN
    pushfq
    DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI)
    + TRACE_IRQS_OFF
    SWAPGS
    .Lgs_change:
    movl %edi, %gs
    2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE
    SWAPGS
    + TRACE_IRQS_FLAGS (%rsp)
    popfq
    FRAME_END
    ret

    \
     
     \ /
      Last update: 2017-11-28 12:43    [W:4.720 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site