libgcc patch committed: Avoid hooks in split-stack code

Ian Lance Taylor iant@golang.org
Tue Apr 7 18:31:42 GMT 2020


On Tue, Apr 7, 2020 at 3:33 AM Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Tue, Apr 07, 2020 at 12:19:45PM +0200, Richard Biener via Gcc-patches wrote:
> > On Fri, Apr 3, 2020 at 11:59 PM Ian Lance Taylor via Gcc-patches
> > <gcc-patches@gcc.gnu.org> wrote:
> > >
> > > The split-stack code invokes mmap and munmap with a limited amount of
> > > stack space.  That is fine when the functions just make a system call,
> > > but it's not fine when programs use LD_PRELOAD or linker tricks to add
> > > hooks to mmap/munmap.  Those hooks may use too much stack space,
> > > leading to an obscure program crash.
> > >
> > > Avoid that at least on GNU/Linux by calling __mmap/__munmap instead.
> > >
> > > Bootstrapped and ran Go and split-stack tests on x86_64-pc-linux-gnu.
> > > Committed to mainline.
> >
> > This causes references to GLIBC_PRIVATE exported symbols which is
> > highly undesirable for system integrators (no ABI stability is guaranteed
> > for those).  I opened the regression PR94513 for this.
>
> Yeah, GLIBC_PRIVATE symbols may only be used by glibc itself, not by
> anything else.
> I'd suggest to use syscall function instead (though, that can be interposed
> too).

Sorry about that.  OK, let's try syscall.  I committed this patch.
Bootstrapped and tested on x86_64-pc-linux-gnu, did a small amount of
testing on s390x (but I don't have full access to an s390x system).

Ian

2020-04-07  Ian Lance Taylor  <iant@golang.org>

PR libgcc/94513
* generic-morestack.c: Give up trying to use __mmap/__munmap, use
syscall instead.
-------------- next part --------------
diff --git a/libgcc/generic-morestack.c b/libgcc/generic-morestack.c
index fa2062e2bb3..35764a848f6 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 <sys/syscall.h>
 
-#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__) */
 


More information about the Gcc-patches mailing list