Skip to content

Commit

Permalink
linux-user: Honor PT_GNU_STACK
Browse files Browse the repository at this point in the history
Map the stack executable if required by default or on demand.

Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
Tested-by: Ilya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed Sep 3, 2022
1 parent e84b9fc commit 1ec6049
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
1 change: 1 addition & 0 deletions include/elf.h
Expand Up @@ -31,6 +31,7 @@ typedef int64_t Elf64_Sxword;
#define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7fffffff

#define PT_GNU_STACK (PT_LOOS + 0x474e551)
#define PT_GNU_PROPERTY (PT_LOOS + 0x474e553)

#define PT_MIPS_REGINFO 0x70000000
Expand Down
19 changes: 18 additions & 1 deletion linux-user/elfload.c
Expand Up @@ -232,6 +232,7 @@ static bool init_guest_commpage(void)
#define ELF_ARCH EM_386

#define ELF_PLATFORM get_elf_platform()
#define EXSTACK_DEFAULT true

static const char *get_elf_platform(void)
{
Expand Down Expand Up @@ -308,6 +309,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en

#define ELF_ARCH EM_ARM
#define ELF_CLASS ELFCLASS32
#define EXSTACK_DEFAULT true

static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
Expand Down Expand Up @@ -776,6 +778,7 @@ static inline void init_thread(struct target_pt_regs *regs,
#else

#define ELF_CLASS ELFCLASS32
#define EXSTACK_DEFAULT true

#endif

Expand Down Expand Up @@ -973,6 +976,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en

#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_LOONGARCH
#define EXSTACK_DEFAULT true

#define elf_check_arch(x) ((x) == EM_LOONGARCH)

Expand Down Expand Up @@ -1068,6 +1072,7 @@ static uint32_t get_elf_hwcap(void)
#define ELF_CLASS ELFCLASS32
#endif
#define ELF_ARCH EM_MIPS
#define EXSTACK_DEFAULT true

#ifdef TARGET_ABI_MIPSN32
#define elf_check_abi(x) ((x) & EF_MIPS_ABI2)
Expand Down Expand Up @@ -1806,6 +1811,10 @@ static inline void init_thread(struct target_pt_regs *regs,
#define bswaptls(ptr) bswap32s(ptr)
#endif

#ifndef EXSTACK_DEFAULT
#define EXSTACK_DEFAULT false
#endif

#include "elf.h"

/* We must delay the following stanzas until after "elf.h". */
Expand Down Expand Up @@ -2081,6 +2090,7 @@ static abi_ulong setup_arg_pages(struct linux_binprm *bprm,
struct image_info *info)
{
abi_ulong size, error, guard;
int prot;

size = guest_stack_size;
if (size < STACK_LOWER_LIMIT) {
Expand All @@ -2091,7 +2101,11 @@ static abi_ulong setup_arg_pages(struct linux_binprm *bprm,
guard = qemu_real_host_page_size();
}

error = target_mmap(0, size + guard, PROT_READ | PROT_WRITE,
prot = PROT_READ | PROT_WRITE;
if (info->exec_stack) {
prot |= PROT_EXEC;
}
error = target_mmap(0, size + guard, prot,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (error == -1) {
perror("mmap stack");
Expand Down Expand Up @@ -2921,6 +2935,7 @@ static void load_elf_image(const char *image_name, int image_fd,
*/
loaddr = -1, hiaddr = 0;
info->alignment = 0;
info->exec_stack = EXSTACK_DEFAULT;
for (i = 0; i < ehdr->e_phnum; ++i) {
struct elf_phdr *eppnt = phdr + i;
if (eppnt->p_type == PT_LOAD) {
Expand Down Expand Up @@ -2963,6 +2978,8 @@ static void load_elf_image(const char *image_name, int image_fd,
if (!parse_elf_properties(image_fd, info, eppnt, bprm_buf, &err)) {
goto exit_errmsg;
}
} else if (eppnt->p_type == PT_GNU_STACK) {
info->exec_stack = eppnt->p_flags & PF_X;
}
}

Expand Down
1 change: 1 addition & 0 deletions linux-user/qemu.h
Expand Up @@ -48,6 +48,7 @@ struct image_info {
uint32_t elf_flags;
int personality;
abi_ulong alignment;
bool exec_stack;

/* Generic semihosting knows about these pointers. */
abi_ulong arg_strings; /* strings for argv */
Expand Down

0 comments on commit 1ec6049

Please sign in to comment.