lkml.org 
[lkml]   [2019]   [Jan]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 03/17] x86/mm: temporary mm struct
    Date
    From: Andy Lutomirski <luto@kernel.org>

    Sometimes we want to set a temporary page-table entries (PTEs) in one of
    the cores, without allowing other cores to use - even speculatively -
    these mappings. There are two benefits for doing so:

    (1) Security: if sensitive PTEs are set, temporary mm prevents their use
    in other cores. This hardens the security as it prevents exploding a
    dangling pointer to overwrite sensitive data using the sensitive PTE.

    (2) Avoiding TLB shootdowns: the PTEs do not need to be flushed in
    remote page-tables.

    To do so a temporary mm_struct can be used. Mappings which are private
    for this mm can be set in the userspace part of the address-space.
    During the whole time in which the temporary mm is loaded, interrupts
    must be disabled.

    The first use-case for temporary PTEs, which will follow, is for poking
    the kernel text.

    [ Commit message was written by Nadav ]

    Cc: Kees Cook <keescook@chromium.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Dave Hansen <dave.hansen@intel.com>
    Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
    Tested-by: Masami Hiramatsu <mhiramat@kernel.org>
    Signed-off-by: Andy Lutomirski <luto@kernel.org>
    Signed-off-by: Nadav Amit <namit@vmware.com>
    Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
    ---
    arch/x86/include/asm/mmu_context.h | 32 ++++++++++++++++++++++++++++++
    1 file changed, 32 insertions(+)

    diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
    index 0ca50611e8ce..0141b7fa6d01 100644
    --- a/arch/x86/include/asm/mmu_context.h
    +++ b/arch/x86/include/asm/mmu_context.h
    @@ -338,4 +338,36 @@ static inline unsigned long __get_current_cr3_fast(void)
    return cr3;
    }

    +typedef struct {
    + struct mm_struct *prev;
    +} temporary_mm_state_t;
    +
    +/*
    + * Using a temporary mm allows to set temporary mappings that are not accessible
    + * by other cores. Such mappings are needed to perform sensitive memory writes
    + * that override the kernel memory protections (e.g., W^X), without exposing the
    + * temporary page-table mappings that are required for these write operations to
    + * other cores.
    + *
    + * Context: The temporary mm needs to be used exclusively by a single core. To
    + * harden security IRQs must be disabled while the temporary mm is
    + * loaded, thereby preventing interrupt handler bugs from override the
    + * kernel memory protection.
    + */
    +static inline temporary_mm_state_t use_temporary_mm(struct mm_struct *mm)
    +{
    + temporary_mm_state_t state;
    +
    + lockdep_assert_irqs_disabled();
    + state.prev = this_cpu_read(cpu_tlbstate.loaded_mm);
    + switch_mm_irqs_off(NULL, mm, current);
    + return state;
    +}
    +
    +static inline void unuse_temporary_mm(temporary_mm_state_t prev)
    +{
    + lockdep_assert_irqs_disabled();
    + switch_mm_irqs_off(NULL, prev.prev, current);
    +}
    +
    #endif /* _ASM_X86_MMU_CONTEXT_H */
    --
    2.17.1
    \
     
     \ /
      Last update: 2019-01-17 01:37    [W:4.333 / U:0.112 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site