lkml.org 
[lkml]   [2020]   [Oct]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v14 23/26] ELF: Introduce arch_setup_elf_property()
    Date
    An ELF file's .note.gnu.property indicates arch features supported by the
    file. These features are extracted by arch_parse_elf_property() and stored
    in 'arch_elf_state'. Introduce arch_setup_elf_property() for enabling such
    features. The first use-case of this function is shadow stack.

    ARM64 is the other arch that has ARCH_USER_GNU_PROPERTY and arch_parse_elf_
    property(). Add arch_setup_elf_property() for it.

    Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
    Cc: Mark Brown <broonie@kernel.org>
    Cc: Catalin Marinas <catalin.marinas@arm.com>
    Cc: Dave Martin <Dave.Martin@arm.com>
    ---
    arch/arm64/include/asm/elf.h | 5 +++++
    arch/x86/Kconfig | 2 ++
    arch/x86/include/asm/elf.h | 13 +++++++++++++
    arch/x86/kernel/process_64.c | 32 ++++++++++++++++++++++++++++++++
    fs/binfmt_elf.c | 4 ++++
    include/linux/elf.h | 6 ++++++
    6 files changed, 62 insertions(+)

    diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
    index 8d1c8dcb87fd..d37bc7915935 100644
    --- a/arch/arm64/include/asm/elf.h
    +++ b/arch/arm64/include/asm/elf.h
    @@ -281,6 +281,11 @@ static inline int arch_parse_elf_property(u32 type, const void *data,
    return 0;
    }

    +static inline int arch_setup_elf_property(struct arch_elf_state *arch)
    +{
    + return 0;
    +}
    +
    static inline int arch_elf_pt_proc(void *ehdr, void *phdr,
    struct file *f, bool is_interp,
    struct arch_elf_state *state)
    diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
    index 7578327226e3..4b28a0ce4594 100644
    --- a/arch/x86/Kconfig
    +++ b/arch/x86/Kconfig
    @@ -1950,6 +1950,8 @@ config X86_SHADOW_STACK_USER
    select X86_CET
    select ARCH_MAYBE_MKWRITE
    select ARCH_HAS_SHADOW_STACK
    + select ARCH_USE_GNU_PROPERTY
    + select ARCH_BINFMT_ELF_STATE
    help
    Shadow Stacks provides protection against program stack
    corruption. It's a hardware feature. This only matters
    diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
    index b9a5d488f1a5..0e1be2a13359 100644
    --- a/arch/x86/include/asm/elf.h
    +++ b/arch/x86/include/asm/elf.h
    @@ -385,6 +385,19 @@ extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
    int uses_interp);
    #define compat_arch_setup_additional_pages compat_arch_setup_additional_pages

    +#ifdef CONFIG_ARCH_BINFMT_ELF_STATE
    +struct arch_elf_state {
    + unsigned int gnu_property;
    +};
    +
    +#define INIT_ARCH_ELF_STATE { \
    + .gnu_property = 0, \
    +}
    +
    +#define arch_elf_pt_proc(ehdr, phdr, elf, interp, state) (0)
    +#define arch_check_elf(ehdr, interp, interp_ehdr, state) (0)
    +#endif
    +
    /* Do not change the values. See get_align_mask() */
    enum align_flags {
    ALIGN_VA_32 = BIT(0),
    diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
    index 9afefe325acb..8725e67bcd44 100644
    --- a/arch/x86/kernel/process_64.c
    +++ b/arch/x86/kernel/process_64.c
    @@ -837,3 +837,35 @@ unsigned long KSTK_ESP(struct task_struct *task)
    {
    return task_pt_regs(task)->sp;
    }
    +
    +#ifdef CONFIG_ARCH_USE_GNU_PROPERTY
    +int arch_parse_elf_property(u32 type, const void *data, size_t datasz,
    + bool compat, struct arch_elf_state *state)
    +{
    + if (type != GNU_PROPERTY_X86_FEATURE_1_AND)
    + return 0;
    +
    + if (datasz != sizeof(unsigned int))
    + return -ENOEXEC;
    +
    + state->gnu_property = *(unsigned int *)data;
    + return 0;
    +}
    +
    +int arch_setup_elf_property(struct arch_elf_state *state)
    +{
    + int r = 0;
    +
    + if (!IS_ENABLED(CONFIG_X86_CET))
    + return r;
    +
    + memset(&current->thread.cet, 0, sizeof(struct cet_status));
    +
    + if (static_cpu_has(X86_FEATURE_SHSTK)) {
    + if (state->gnu_property & GNU_PROPERTY_X86_FEATURE_1_SHSTK)
    + r = cet_setup_shstk();
    + }
    +
    + return r;
    +}
    +#endif
    diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
    index 13d053982dd7..2b4cfc256895 100644
    --- a/fs/binfmt_elf.c
    +++ b/fs/binfmt_elf.c
    @@ -1217,6 +1217,10 @@ static int load_elf_binary(struct linux_binprm *bprm)

    set_binfmt(&elf_format);

    + retval = arch_setup_elf_property(&arch_state);
    + if (retval < 0)
    + goto out;
    +
    #ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
    retval = arch_setup_additional_pages(bprm, !!interpreter);
    if (retval < 0)
    diff --git a/include/linux/elf.h b/include/linux/elf.h
    index 5d5b0321da0b..4827695ca415 100644
    --- a/include/linux/elf.h
    +++ b/include/linux/elf.h
    @@ -82,9 +82,15 @@ static inline int arch_parse_elf_property(u32 type, const void *data,
    {
    return 0;
    }
    +
    +static inline int arch_setup_elf_property(struct arch_elf_state *arch)
    +{
    + return 0;
    +}
    #else
    extern int arch_parse_elf_property(u32 type, const void *data, size_t datasz,
    bool compat, struct arch_elf_state *arch);
    +extern int arch_setup_elf_property(struct arch_elf_state *arch);
    #endif

    #ifdef CONFIG_ARCH_HAVE_ELF_PROT
    --
    2.21.0
    \
     
     \ /
      Last update: 2020-10-12 17:40    [W:4.199 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site