RE: [RFC PATCH v3 2/2] MIPS: non-exec stack & heap when non-exec PT_GNU_STACK is present

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Paul Burton <Paul.Burton@xxxxxxxxxx> writes:
> The stack and heap have both been executable by default on MIPS until
> now. This patch changes the default to be non-executable, but only for
> ELF binaries with a non-executable PT_GNU_STACK header present. This
> does apply to both the heap & the stack, despite the name PT_GNU_STACK,
> and this matches the behaviour of other architectures like ARM & x86.
> 
> Current MIPS toolchains do not produce the PT_GNU_STACK header, which
> means that we can rely upon this patch not changing the behaviour of
> existing binaries. The new default will only take effect for newly
> compiled binaries once toolchains are updated to support PT_GNU_STACK,
> and since those binaries are newly compiled they can be compiled
> expecting the change in default behaviour. Again this matches the way in
> which the ARM & x86 architectures handled their implementations of
> non-executable memory.

There will be some extra work on top of this to inform user-mode that
no-exec-stack support is actually safe. I'm a bit fuzzy on the exact
details though as I have not been directly involved for a while.

https://www.sourceware.org/ml/libc-alpha/2016-01/msg00719.html

Adding Faraz who worked on the user-mode side and Maciej who has been
reviewing.

Thanks,
Matthew

> 
> Signed-off-by: Paul Burton <paul.burton@xxxxxxxxxx>
> 
> ---
> 
> Changes in v3:
> - Rebase atop v4.7-rc5.
> 
> Changes in v2: None
> 
>  arch/mips/include/asm/elf.h  |  5 +++++
>  arch/mips/include/asm/page.h |  6 ++++--
>  arch/mips/kernel/elf.c       | 19 +++++++++++++++++++
>  3 files changed, 28 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
> index f5f4571..914981d 100644
> --- a/arch/mips/include/asm/elf.h
> +++ b/arch/mips/include/asm/elf.h
> @@ -498,4 +498,9 @@ extern int arch_check_elf(void *ehdr, bool has_interpreter, void
> *interp_ehdr,
>  extern void mips_set_personality_nan(struct arch_elf_state *state);
>  extern void mips_set_personality_fp(struct arch_elf_state *state);
> 
> +#define elf_read_implies_exec(ex, stk) mips_elf_read_implies_exec(&(ex), stk)
> +struct elf32_hdr;
> +extern int mips_elf_read_implies_exec(const struct elf32_hdr *elf_ex,
> +				      int exstack);
> +
>  #endif /* _ASM_ELF_H */
> diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
> index 21ed715..74cb004 100644
> --- a/arch/mips/include/asm/page.h
> +++ b/arch/mips/include/asm/page.h
> @@ -229,8 +229,10 @@ extern int __virt_addr_valid(const volatile void *kaddr);
>  #define virt_addr_valid(kaddr)						\
>  	__virt_addr_valid((const volatile void *) (kaddr))
> 
> -#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
> -				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
> +#define VM_DATA_DEFAULT_FLAGS \
> +	(VM_READ | VM_WRITE | \
> +	 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
> +	 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
> 
>  #define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE)
>  #define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET)
> diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c
> index 891f5ee..9aa55b8 100644
> --- a/arch/mips/kernel/elf.c
> +++ b/arch/mips/kernel/elf.c
> @@ -8,9 +8,12 @@
>   * option) any later version.
>   */
> 
> +#include <linux/binfmts.h>
>  #include <linux/elf.h>
> +#include <linux/export.h>
>  #include <linux/sched.h>
> 
> +#include <asm/cpu-features.h>
>  #include <asm/cpu-info.h>
> 
>  /* Whether to accept legacy-NaN and 2008-NaN user binaries.  */
> @@ -326,3 +329,19 @@ void mips_set_personality_nan(struct arch_elf_state *state)
>  		BUG();
>  	}
>  }
> +
> +int mips_elf_read_implies_exec(const struct elf32_hdr *elf_ex, int exstack)
> +{
> +	if (exstack != EXSTACK_DISABLE_X) {
> +		/* The binary doesn't request a non-executable stack */
> +		return 1;
> +	}
> +
> +	if (!cpu_has_rixi) {
> +		/* The CPU doesn't support non-executable memory */
> +		return 1;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(mips_elf_read_implies_exec);
> --
> 2.9.0





[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux