aboutsummaryrefslogtreecommitdiff
path: root/linux-user/mmap.c
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2022-09-24 13:45:00 +0200
committerLaurent Vivier <laurent@vivier.eu>2022-09-27 13:18:53 +0200
commit4c184e70ad01289f89a9a780d154b00d6a86cccd (patch)
treed6f452ac3b3b6695e0cdff047ff376b79f595920 /linux-user/mmap.c
parent0a3346b5938530178e20abea5219e80130cf0204 (diff)
downloadqemu-4c184e70ad01289f89a9a780d154b00d6a86cccd.zip
qemu-4c184e70ad01289f89a9a780d154b00d6a86cccd.tar.gz
qemu-4c184e70ad01289f89a9a780d154b00d6a86cccd.tar.bz2
linux-user/hppa: Allow PROT_GROWSUP and PROT_GROWSDOWN in mprotect()
The hppa platform uses an upwards-growing stack and required in Linux kernels < 5.18 an executable stack for signal processing. For that some executables and libraries are marked to have an executable stack, for which glibc uses the mprotect() syscall to mark the stack like this: mprotect(xfa000000,4096,PROT_EXEC|PROT_READ|PROT_WRITE|PROT_GROWSUP). Currently qemu will return -TARGET_EINVAL for this syscall because of the checks in validate_prot_to_pageflags(), which doesn't allow the PROT_GROWSUP or PROT_GROWSDOWN flags and thus triggers this error in the guest: error while loading shared libraries: libc.so.6: cannot enable executable stack as shared object requires: Invalid argument Allow mprotect() to handle both flags and thus fix the guest. The glibc tst-execstack testcase can be used to reproduce the issue. Signed-off-by: Helge Deller <deller@gmx.de> Message-Id: <20220924114501.21767-7-deller@gmx.de> [lvivier: s/elif TARGET_HPPA/elif defined(TARGET_HPPA)/] Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Diffstat (limited to 'linux-user/mmap.c')
-rw-r--r--linux-user/mmap.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index e557f36..28f3bc8 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -106,6 +106,8 @@ static int validate_prot_to_pageflags(int *host_prot, int prot)
page_flags |= PAGE_MTE;
}
}
+#elif defined(TARGET_HPPA)
+ valid |= PROT_GROWSDOWN | PROT_GROWSUP;
#endif
return prot & ~valid ? 0 : page_flags;