linux-user: Honor PT_GNU_STACK
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>
This commit is contained in:
parent
d461b73ec0
commit
872f3d046f
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
@ -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)
|
||||
@ -776,6 +778,7 @@ static inline void init_thread(struct target_pt_regs *regs,
|
||||
#else
|
||||
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define EXSTACK_DEFAULT true
|
||||
|
||||
#endif
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
@ -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". */
|
||||
@ -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) {
|
||||
@ -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");
|
||||
@ -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) {
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user