]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
aarch64: enforce >=64K guard size [BZ #26691]
authorSzabolcs Nagy <szabolcs.nagy@arm.com>
Wed, 13 Dec 2017 15:50:21 +0000 (15:50 +0000)
committerSzabolcs Nagy <szabolcs.nagy@arm.com>
Fri, 2 Oct 2020 08:57:44 +0000 (09:57 +0100)
There are several compiler implementations that allow large stack
allocations to jump over the guard page at the end of the stack and
corrupt memory beyond that. See CVE-2017-1000364.

Compilers can emit code to probe the stack such that the guard page
cannot be skipped, but on aarch64 the probe interval is 64K by default
instead of the minimum supported page size (4K).

This patch enforces at least 64K guard on aarch64 unless the guard
is disabled by setting its size to 0.  For backward compatibility
reasons the increased guard is not reported, so it is only observable
by exhausting the address space or parsing /proc/self/maps on linux.

On other targets the patch has no effect. If the stack probe interval
is larger than a page size on a target then ARCH_MIN_GUARD_SIZE can
be defined to get large enough stack guard on libc allocated stacks.

The patch does not affect threads with user allocated stacks.

Fixes bug 26691.

20 files changed:
nptl/allocatestack.c
sysdeps/aarch64/nptl/pthreaddef.h
sysdeps/alpha/nptl/pthreaddef.h
sysdeps/arc/nptl/pthreaddef.h
sysdeps/arm/nptl/pthreaddef.h
sysdeps/csky/nptl/pthreaddef.h
sysdeps/hppa/nptl/pthreaddef.h
sysdeps/i386/nptl/pthreaddef.h
sysdeps/ia64/nptl/pthreaddef.h
sysdeps/m68k/nptl/pthreaddef.h
sysdeps/microblaze/nptl/pthreaddef.h
sysdeps/mips/nptl/pthreaddef.h
sysdeps/nios2/nptl/pthreaddef.h
sysdeps/powerpc/nptl/pthreaddef.h
sysdeps/riscv/nptl/pthreaddef.h
sysdeps/s390/nptl/pthreaddef.h
sysdeps/sh/nptl/pthreaddef.h
sysdeps/sparc/sparc32/pthreaddef.h
sysdeps/sparc/sparc64/pthreaddef.h
sysdeps/x86_64/nptl/pthreaddef.h

index 4ae4b5a9862f35f7f42ceb775094c85320203cce..4b45f8c884b81850ff2b7ca56fe5bf10d0ea2207 100644 (file)
@@ -521,6 +521,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
     {
       /* Allocate some anonymous memory.  If possible use the cache.  */
       size_t guardsize;
+      size_t reported_guardsize;
       size_t reqsize;
       void *mem;
       const int prot = (PROT_READ | PROT_WRITE
@@ -531,8 +532,17 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
       assert (size != 0);
 
       /* Make sure the size of the stack is enough for the guard and
-        eventually the thread descriptor.  */
+        eventually the thread descriptor.  On some targets there is
+        a minimum guard size requirement, ARCH_MIN_GUARD_SIZE, so
+        internally enforce it (unless the guard was disabled), but
+        report the original guard size for backward compatibility:
+        before POSIX 2008 the guardsize was specified to be one page
+        by default which is observable via pthread_attr_getguardsize
+        and pthread_getattr_np.  */
       guardsize = (attr->guardsize + pagesize_m1) & ~pagesize_m1;
+      reported_guardsize = guardsize;
+      if (guardsize > 0 && guardsize < ARCH_MIN_GUARD_SIZE)
+       guardsize = ARCH_MIN_GUARD_SIZE;
       if (guardsize < attr->guardsize || size + guardsize < guardsize)
        /* Arithmetic overflow.  */
        return EINVAL;
@@ -740,7 +750,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
       /* The pthread_getattr_np() calls need to get passed the size
         requested in the attribute, regardless of how large the
         actually used guardsize is.  */
-      pd->reported_guardsize = guardsize;
+      pd->reported_guardsize = reported_guardsize;
     }
 
   /* Initialize the lock.  We have to do this unconditionally since the
index 892b869fc23385e30dc2048a5a1c4a605296fc8a..b865fd5fab5474ef33f17f9391636934e4715e31 100644 (file)
@@ -19,6 +19,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE (64 * 1024)
+
 /* Required stack pointer alignment at beginning.  */
 #define STACK_ALIGN 16
 
index 6ec8f49f39d1a54d262ba419b66b522064d56de8..c710b04845d6be848c860eea83e035fc1458525e 100644 (file)
@@ -18,6 +18,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (4 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  The ABI requires 16.  */
 #define STACK_ALIGN            16
 
index 5c2b752becad28479bd16597ae2dba48bbaf42a0..844b213729105cb02b3eb2dff0907cb11ed7aaad 100644 (file)
@@ -19,6 +19,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  */
 #define STACK_ALIGN            4
 
index 5b05f2a8bd2e2a040e92735920b4d44a5006669e..3e21cbd39a656ff825655509c535fff6ee197c94 100644 (file)
@@ -18,6 +18,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  SSE requires 16
    bytes.  */
 #define STACK_ALIGN            16
index 98b9546b12c77c4f0a14cf2a6e628974a2b1c381..f4b0b4c8473db1db7c3a948da6158c08cbcde695 100644 (file)
@@ -19,6 +19,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  */
 #define STACK_ALIGN            8
 
index 9fab974e7d141fd536a6508a66a4df887cdfb25a..5dd4fec20db095e7257b9bc5c58bfe29ab78b732 100644 (file)
@@ -18,6 +18,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (8 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  */
 #define STACK_ALIGN            64
 
index 65d5bc9b2ef71fc1964c535e6ffa4f9466bb70a2..db833351c6fc0dd31691b39c1473cc9eff718c7e 100644 (file)
@@ -19,6 +19,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  SSE requires 16
    bytes.  */
 #define STACK_ALIGN            16
index 42a95e6b24b21bc6377cc8c56b01c736b4a45c02..26c509abe2587aa97db20cc5bb542f42714e7f44 100644 (file)
@@ -18,6 +18,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (32 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* IA-64 uses a normal stack and a register stack.  */
 #define NEED_SEPARATE_REGISTER_STACK
 
index baca43951dcb7c6855b81a1c096a1c831f2e7ea6..8d0253ba4cfbe631d715ea6f828ed53532fae0e2 100644 (file)
@@ -19,6 +19,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  */
 #define STACK_ALIGN            16
 
index c043372f4466bcf1a7dfdd0529ef905e2c594130..73b4a42971fe45aad59f40567fb98b4304cd96b8 100644 (file)
@@ -22,6 +22,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE  (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  */
 #define STACK_ALIGN         16
 
index fa232b0c783cd3cc795cf5cb59e3555bded35e6e..8305c23940c169a29001aba362d7dc361fa8fe8c 100644 (file)
@@ -18,6 +18,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  */
 #define STACK_ALIGN            16
 
index 4ae7d4581c9ebf7a11c45b7a3943427ce7d59ffa..590e3f87747520828bfaaa5896a1f8e4c7325dea 100644 (file)
@@ -19,6 +19,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  */
 #define STACK_ALIGN            4
 
index 4abdc480c4beddfd7af5d2ff3c88853692034f14..70e55b70f01ced98a3788cf15accee2323efe3af 100644 (file)
@@ -18,6 +18,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (4 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  The ABI requires 16
    bytes (for both 32-bit and 64-bit PowerPC).  */
 #define STACK_ALIGN            16
index 146c04f63a685be015cdd7fb7faf9ea68ec9a54e..b45359faf7ee90247cfc94fba55cfb9ce75df72c 100644 (file)
@@ -19,6 +19,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  */
 #define STACK_ALIGN            16
 
index e087e1cddfb3fbe90de913787ca76454846f0d36..c218271fc393c97cbb423d421a7e9fe78777a1d8 100644 (file)
@@ -18,6 +18,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  SSE requires 16
    bytes.  */
 #define STACK_ALIGN            16
index 12106e79e1b6756b865e29f5f770a545d547abc6..50cedcefa6c068abb2bfae8c860e535c4b720fcd 100644 (file)
@@ -20,6 +20,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  */
 #define STACK_ALIGN            8
 
index 403fa3e34002354d39a5fc050c804dcd9d65e163..41de22b3be8a4a5e1c2351ef0e0dc976fa804c26 100644 (file)
@@ -18,6 +18,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  */
 #define STACK_ALIGN            16
 
index 0a0841262ad8b01cf7094fbb6a19c11c40d3ba3f..363b0f9e4137649cf5648bade94e80949e384baa 100644 (file)
@@ -18,6 +18,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (4 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  */
 #define STACK_ALIGN            16
 
index d49848da3c1b1fe3c120a016a9d2c08cc9580c1c..5554876bfcd308265e92c0b4262ba2c6325f13be 100644 (file)
@@ -19,6 +19,9 @@
 /* Default stack size.  */
 #define ARCH_STACK_DEFAULT_SIZE        (2 * 1024 * 1024)
 
+/* Minimum guard size.  */
+#define ARCH_MIN_GUARD_SIZE 0
+
 /* Required stack pointer alignment at beginning.  SSE requires 16
    bytes.  */
 #define STACK_ALIGN            16