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 4ae4b5a..4b45f8c 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 892b869..b865fd5 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 6ec8f49..c710b04 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 5c2b752..844b213 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 5b05f2a..3e21cbd 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 98b9546..f4b0b4c 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 9fab974..5dd4fec 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 65d5bc9..db83335 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 42a95e6..26c509a 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 baca439..8d0253b 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 c043372..73b4a42 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 fa232b0..8305c23 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 4ae7d45..590e3f8 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 4abdc48..70e55b7 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 146c04f..b45359f 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 e087e1c..c218271 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 12106e7..50cedce 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 403fa3e..41de22b 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 0a08412..363b0f9 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 d49848d..5554876 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