From 710d54ed4e343a08d2fa0abc6b63c53dec0d9bcb Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 3 Apr 2020 14:57:18 -0700 Subject: libgcc: avoid mmap/munmap hooks in split-stack code on GNU/Linux * generic-morestack.c: On GNU/Linux use __mmap/__munmap rather than mmap/munmap, to avoid hooks. --- libgcc/generic-morestack.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'libgcc/generic-morestack.c') diff --git a/libgcc/generic-morestack.c b/libgcc/generic-morestack.c index c26dba1..bb9f67a 100644 --- a/libgcc/generic-morestack.c +++ b/libgcc/generic-morestack.c @@ -53,6 +53,23 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "generic-morestack.h" +/* Some systems use LD_PRELOAD or similar tricks to add hooks to + mmap/munmap. That breaks this code, because when we call mmap + there is enough stack space for the system call but there is not, + in general, enough stack space to run a hook. At least when using + glibc on GNU/Linux we can avoid the problem by calling __mmap and + __munmap. */ + +#ifdef __gnu_linux__ + +extern void *__mmap (void *, size_t, int, int, int, off_t); +extern int __munmap (void *, size_t); + +#define mmap __mmap +#define munmap __munmap + +#endif /* defined(__gnu_linux__) */ + typedef unsigned uintptr_type __attribute__ ((mode (pointer))); /* This file contains subroutines that are used by code compiled with -- cgit v1.1 From 458ca332d104240e7752eb1765660141fef878bd Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 4 Apr 2020 13:45:45 -0700 Subject: libgcc: only use __mmap if glibc >- 2.26 * generic-morestack.c: Only use __mmap on glibc >= 2.26. --- libgcc/generic-morestack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libgcc/generic-morestack.c') diff --git a/libgcc/generic-morestack.c b/libgcc/generic-morestack.c index bb9f67a..fa2062e 100644 --- a/libgcc/generic-morestack.c +++ b/libgcc/generic-morestack.c @@ -60,7 +60,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see glibc on GNU/Linux we can avoid the problem by calling __mmap and __munmap. */ -#ifdef __gnu_linux__ +#if defined(__gnu_linux__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 26)) extern void *__mmap (void *, size_t, int, int, int, off_t); extern int __munmap (void *, size_t); -- cgit v1.1 From 50c7853216e8511971c55b51d7fe29173db4749b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 7 Apr 2020 11:29:41 -0700 Subject: libgcc: use syscall rather than __mmap/__munmap PR libgcc/94513 * generic-morestack.c: Give up trying to use __mmap/__munmap, use syscall instead. --- libgcc/generic-morestack.c | 55 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 8 deletions(-) (limited to 'libgcc/generic-morestack.c') diff --git a/libgcc/generic-morestack.c b/libgcc/generic-morestack.c index fa2062e..35764a8 100644 --- a/libgcc/generic-morestack.c +++ b/libgcc/generic-morestack.c @@ -56,17 +56,56 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Some systems use LD_PRELOAD or similar tricks to add hooks to mmap/munmap. That breaks this code, because when we call mmap there is enough stack space for the system call but there is not, - in general, enough stack space to run a hook. At least when using - glibc on GNU/Linux we can avoid the problem by calling __mmap and - __munmap. */ + in general, enough stack space to run a hook. Try to avoid the + problem by calling syscall directly. We only do this on GNU/Linux + for now, but it should be easy to add support for more systems with + testing. */ -#if defined(__gnu_linux__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 26)) +#if defined(__gnu_linux__) -extern void *__mmap (void *, size_t, int, int, int, off_t); -extern int __munmap (void *, size_t); +#include -#define mmap __mmap -#define munmap __munmap +#if defined(SYS_mmap) || defined(SYS_mmap2) + +#ifdef SYS_mmap2 +#define MORESTACK_MMAP SYS_mmap2 +#define MORESTACK_ADJUST_OFFSET(x) ((x) / 4096ULL) +#else +#define MORESTACK_MMAP SYS_mmap +#define MORESTACK_ADJUST_OFFSET(x) (x) +#endif + +static void * +morestack_mmap (void *addr, size_t length, int prot, int flags, int fd, + off_t offset) +{ + offset = MORESTACK_ADJUST_OFFSET (offset); + +#ifdef __s390__ + long args[6] = { (long) addr, (long) length, (long) prot, (long) flags, + (long) fd, (long) offset }; + return (void *) syscall (MORESTACK_MMAP, args); +#else + return (void *) syscall (MORESTACK_MMAP, addr, length, prot, flags, fd, + offset); +#endif +} + +#define mmap morestack_mmap + +#endif /* defined(SYS_MMAP) || defined(SYS_mmap2) */ + +#if defined(SYS_munmap) + +static int +morestack_munmap (void * addr, size_t length) +{ + return (int) syscall (SYS_munmap, addr, length); +} + +#define munmap morestack_munmap + +#endif /* defined(SYS_munmap) */ #endif /* defined(__gnu_linux__) */ -- cgit v1.1