lkml.org 
[lkml]   [2023]   [Jun]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 13/13] x86/jitalloc: make memory allocated for code ROX
    Date
    From: "Mike Rapoport (IBM)" <rppt@kernel.org>

    When STRICT_KERNEL_RWX or STRICT_MODULE_RWX is enabled, force text
    allocations to use KERNEL_PAGE_ROX.

    Signed-off-by: Mike Rapoport (IBM) <rppt@kernel.org>
    ---
    arch/Kconfig | 3 +++
    arch/x86/Kconfig | 1 +
    arch/x86/kernel/ftrace.c | 3 ---
    arch/x86/mm/init.c | 6 ++++++
    include/linux/jitalloc.h | 2 ++
    mm/jitalloc.c | 21 +++++++++++++++++++++
    6 files changed, 33 insertions(+), 3 deletions(-)

    diff --git a/arch/Kconfig b/arch/Kconfig
    index 479a7b8be191..e7c4b01307d7 100644
    --- a/arch/Kconfig
    +++ b/arch/Kconfig
    @@ -1307,6 +1307,9 @@ config STRICT_MODULE_RWX
    and non-text memory will be made non-executable. This provides
    protection against certain security exploits (e.g. writing to text)

    +config ARCH_HAS_TEXT_POKE
    + def_bool n
    +
    # select if the architecture provides an asm/dma-direct.h header
    config ARCH_HAS_PHYS_TO_DMA
    bool
    diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
    index fac4add6ce16..e1a512f557de 100644
    --- a/arch/x86/Kconfig
    +++ b/arch/x86/Kconfig
    @@ -96,6 +96,7 @@ config X86
    select ARCH_HAS_SET_DIRECT_MAP
    select ARCH_HAS_STRICT_KERNEL_RWX
    select ARCH_HAS_STRICT_MODULE_RWX
    + select ARCH_HAS_TEXT_POKE
    select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
    select ARCH_HAS_SYSCALL_WRAPPER
    select ARCH_HAS_UBSAN_SANITIZE_ALL
    diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
    index d50595f2c1a6..bd4dd8974ee6 100644
    --- a/arch/x86/kernel/ftrace.c
    +++ b/arch/x86/kernel/ftrace.c
    @@ -313,7 +313,6 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
    unsigned long call_offset;
    unsigned long jmp_offset;
    unsigned long offset;
    - unsigned long npages;
    unsigned long size;
    unsigned long *ptr;
    void *trampoline;
    @@ -350,7 +349,6 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
    return 0;

    *tramp_size = size + RET_SIZE + sizeof(void *);
    - npages = DIV_ROUND_UP(*tramp_size, PAGE_SIZE);

    /* Copy ftrace_caller onto the trampoline memory */
    ret = text_poke_copy(trampoline, (void *)start_offset, size);
    @@ -416,7 +414,6 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
    /* ALLOC_TRAMP flags lets us know we created it */
    ops->flags |= FTRACE_OPS_FL_ALLOC_TRAMP;

    - set_memory_rox((unsigned long)trampoline, npages);
    return (unsigned long)trampoline;
    fail:
    tramp_free(trampoline);
    diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
    index ffaf9a3840ce..c314738991fa 100644
    --- a/arch/x86/mm/init.c
    +++ b/arch/x86/mm/init.c
    @@ -1127,6 +1127,12 @@ struct jit_alloc_params *jit_alloc_arch_params(void)
    jit_alloc_params.text.start = MODULES_VADDR + get_jit_load_offset();
    jit_alloc_params.text.end = MODULES_END;

    + if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX) ||
    + IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) {
    + jit_alloc_params.text.pgprot = PAGE_KERNEL_ROX;
    + jit_alloc_params.flags |= JIT_ALLOC_USE_TEXT_POKE;
    + }
    +
    return &jit_alloc_params;
    }
    #endif /* CONFIG_JIT_ALLOC */
    diff --git a/include/linux/jitalloc.h b/include/linux/jitalloc.h
    index 0ba5ef785a85..0e29e87acefe 100644
    --- a/include/linux/jitalloc.h
    +++ b/include/linux/jitalloc.h
    @@ -15,9 +15,11 @@
    /**
    * enum jit_alloc_flags - options for executable memory allocations
    * @JIT_ALLOC_KASAN_SHADOW: allocate kasan shadow
    + * @JIT_ALLOC_USE_TEXT_POKE: use text poking APIs to update memory
    */
    enum jit_alloc_flags {
    JIT_ALLOC_KASAN_SHADOW = (1 << 0),
    + JIT_ALLOC_USE_TEXT_POKE = (1 << 1),
    };

    /**
    diff --git a/mm/jitalloc.c b/mm/jitalloc.c
    index a8ae64364d56..15d1067faf3f 100644
    --- a/mm/jitalloc.c
    +++ b/mm/jitalloc.c
    @@ -7,6 +7,26 @@

    static struct jit_alloc_params jit_alloc_params;

    +#ifdef CONFIG_ARCH_HAS_TEXT_POKE
    +#include <asm/text-patching.h>
    +
    +static inline void jit_text_poke_copy(void *dst, const void *src, size_t len)
    +{
    + if (jit_alloc_params.flags & JIT_ALLOC_USE_TEXT_POKE)
    + text_poke_copy(dst, src, len);
    + else
    + memcpy(dst, src, len);
    +}
    +
    +static inline void jit_text_poke_set(void *addr, int c, size_t len)
    +{
    + if (jit_alloc_params.flags & JIT_ALLOC_USE_TEXT_POKE)
    + text_poke_set(addr, c, len);
    + else
    + memset(addr, c, len);
    +}
    +
    +#else
    static inline void jit_text_poke_copy(void *dst, const void *src, size_t len)
    {
    memcpy(dst, src, len);
    @@ -16,6 +36,7 @@ static inline void jit_text_poke_set(void *addr, int c, size_t len)
    {
    memset(addr, c, len);
    }
    +#endif

    static void *jit_alloc(size_t len, unsigned int alignment, pgprot_t pgprot,
    unsigned long start, unsigned long end,
    --
    2.35.1
    \
     
     \ /
      Last update: 2023-06-01 12:21    [W:6.379 / U:0.072 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site