• John Blackwood's avatar
    [PATCH] x86_64: Plug GS leak in arch_prctl() · 97c2803c
    John Blackwood authored
    In linux-2.6.16, we have noticed a problem where the gs base value
    returned from an arch_prtcl(ARCH_GET_GS, ...) call will be incorrect if:
    
       - the current/calling task has NOT set its own gs base yet to a
         non-zero value,
    
       - some other task that ran on the same processor previously set their
         own gs base to a non-zero value.
    
    In this situation, the ARCH_GET_GS code will read and return the
    MSR_KERNEL_GS_BASE msr register.
    
    However, since the __switch_to() code does NOT load/zero the
    MSR_KERNEL_GS_BASE register when the task that is switched IN has a zero
    next->gs value, the caller of arch_prctl(ARCH_GET_GS, ...) will get back
    the value of some previous tasks's gs base value instead of 0.
    
        Change the arch_prctl() ARCH_GET_GS code to only read and return
        the MSR_KERNEL_GS_BASE msr register if the 'gs' register of the calling
        task is non-zero.
    
        Side note: Since in addition to using arch_prctl(ARCH_SET_GS, ...),
        a task can also setup a gs base value by using modify_ldt() and write
        an index value into 'gs' from user space, the patch below reads
        'gs' instead of using thread.gs, since in the modify_ldt() case,
        the thread.gs value will be 0, and incorrect value would be returned
        (the task->thread.gs value).
    
        When the user has not set its own gs base value and the 'gs'
        register is zero, then the MSR_KERNEL_GS_BASE register will not be
        read and a value of zero will be returned by reading and returning
        'task->thread.gs'.
    
        The first patch shown below is an attempt at implementing this
        approach.
    Signed-off-by: default avatarAndi Kleen <ak@suse.de>
    Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
    97c2803c
process.c 19.2 KB