Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
BACKPORT: Split the old READ_IMPLIES_EXEC workaround from executable
Browse files Browse the repository at this point in the history
PT_GNU_STACK now that toolchains long support PT_GNU_STACK marking and
there's no need anymore to force modern programs into having all its
user mappings executable instead of only the stack and the PROT_EXEC
ones.

Disable that automatic READ_IMPLIES_EXEC forcing on x86-64 and
arm64.

Add tables documenting how READ_IMPLIES_EXEC is handled on x86-64, arm
and arm64.

This patch is needed to fix softlock up observed during stress test.

Backport from: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v5.8-rc1&id=ac7b34218a0021bafd1d4c11c54217b930f516b0

Signed-off-by: Kees Cook <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
Reviewed-by: Jason Gunthorpe <[email protected]>
Signed-off-by: Tuan Phan <[email protected]>
  • Loading branch information
tphan-ampere committed Aug 4, 2020
1 parent cb4b1ac commit d6f5dfc
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 6 deletions.
27 changes: 23 additions & 4 deletions arch/arm/kernel/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,32 @@ void elf_set_personality(const struct elf32_hdr *x)
EXPORT_SYMBOL(elf_set_personality);

/*
* Set READ_IMPLIES_EXEC if:
* - the binary requires an executable stack
* - we're running on a CPU which doesn't support NX.
* An executable for which elf_read_implies_exec() returns TRUE will
* have the READ_IMPLIES_EXEC personality flag set automatically.
*
* The decision process for determining the results are:
*
* CPU: | lacks NX* | has NX |
* ELF: | | |
* ---------------------|------------|------------|
* missing PT_GNU_STACK | exec-all | exec-all |
* PT_GNU_STACK == RWX | exec-all | exec-stack |
* PT_GNU_STACK == RW | exec-all | exec-none |
*
* exec-all : all PROT_READ user mappings are executable, except when
* backed by files on a noexec-filesystem.
* exec-none : only PROT_EXEC user mappings are executable.
* exec-stack: only the stack and PROT_EXEC user mappings are executable.
*
* *this column has no architectural effect: NX markings are ignored by
* hardware, but may have behavioral effects when "wants X" collides with
* "cannot be X" constraints in memory permission flags, as in
* https://lkml.kernel.org/r/[email protected]
*
*/
int arm_elf_read_implies_exec(int executable_stack)
{
if (executable_stack != EXSTACK_DISABLE_X)
if (executable_stack == EXSTACK_DEFAULT)
return 1;
if (cpu_architecture() < CPU_ARCH_ARMv6)
return 1;
Expand Down
23 changes: 22 additions & 1 deletion arch/arm64/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,28 @@
*/
#define elf_check_arch(x) ((x)->e_machine == EM_AARCH64)

#define elf_read_implies_exec(ex,stk) (stk != EXSTACK_DISABLE_X)
/*
* An executable for which elf_read_implies_exec() returns TRUE will
* have the READ_IMPLIES_EXEC personality flag set automatically.
*
* The decision process for determining the results are:
*
* CPU*: | arm32 | arm64 |
* ELF: | | |
* ---------------------|------------|------------|
* missing PT_GNU_STACK | exec-all | exec-none |
* PT_GNU_STACK == RWX | exec-stack | exec-stack |
* PT_GNU_STACK == RW | exec-none | exec-none |
*
* exec-all : all PROT_READ user mappings are executable, except when
* backed by files on a noexec-filesystem.
* exec-none : only PROT_EXEC user mappings are executable.
* exec-stack: only the stack and PROT_EXEC user mappings are executable.
*
* *all arm64 CPUs support NX, so there is no "lacks NX" column.
*
*/
#define compat_elf_read_implies_exec(ex, stk) (stk == EXSTACK_DEFAULT)

#define CORE_DUMP_USE_REGSET
#define ELF_EXEC_PAGESIZE PAGE_SIZE
Expand Down
22 changes: 21 additions & 1 deletion arch/x86/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,29 @@ extern u32 elf_hwcap2;
/*
* An executable for which elf_read_implies_exec() returns TRUE will
* have the READ_IMPLIES_EXEC personality flag set automatically.
*
* The decision process for determining the results are:
*
* CPU: | lacks NX* | has NX, ia32 | has NX, x86_64 |
* ELF: | | | |
* ---------------------|------------|------------------|----------------|
* missing PT_GNU_STACK | exec-all | exec-all | exec-none |
* PT_GNU_STACK == RWX | exec-stack | exec-stack | exec-stack |
* PT_GNU_STACK == RW | exec-none | exec-none | exec-none |
*
* exec-all : all PROT_READ user mappings are executable, except when
* backed by files on a noexec-filesystem.
* exec-none : only PROT_EXEC user mappings are executable.
* exec-stack: only the stack and PROT_EXEC user mappings are executable.
*
* *this column has no architectural effect: NX markings are ignored by
* hardware, but may have behavioral effects when "wants X" collides with
* "cannot be X" constraints in memory permission flags, as in
* https://lkml.kernel.org/r/[email protected]
*
*/
#define elf_read_implies_exec(ex, executable_stack) \
(executable_stack != EXSTACK_DISABLE_X)
(mmap_is_ia32() && executable_stack == EXSTACK_DEFAULT)

struct task_struct;

Expand Down
5 changes: 5 additions & 0 deletions fs/compat_binfmt_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@
#define arch_setup_additional_pages compat_arch_setup_additional_pages
#endif

#ifdef compat_elf_read_implies_exec
#undef elf_read_implies_exec
#define elf_read_implies_exec compat_elf_read_implies_exec
#endif

/*
* Rename a few of the symbols that binfmt_elf.c will define.
* These are all local so the names don't really matter, but it
Expand Down

0 comments on commit d6f5dfc

Please sign in to comment.