xref: /llvm-project/compiler-rt/lib/safestack/safestack.cpp (revision 474d35f238d46010d12485734e62de91cb469404)
19642e337SNico Weber //===-- safestack.cpp -----------------------------------------------------===//
29642e337SNico Weber //
39642e337SNico Weber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
49642e337SNico Weber // See https://llvm.org/LICENSE.txt for license information.
59642e337SNico Weber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69642e337SNico Weber //
79642e337SNico Weber //===----------------------------------------------------------------------===//
89642e337SNico Weber //
99642e337SNico Weber // This file implements the runtime support for the safe stack protection
109642e337SNico Weber // mechanism. The runtime manages allocation/deallocation of the unsafe stack
119642e337SNico Weber // for the main thread, as well as all pthreads that are created/destroyed
129642e337SNico Weber // during program execution.
139642e337SNico Weber //
149642e337SNico Weber //===----------------------------------------------------------------------===//
159642e337SNico Weber 
16*474d35f2SRainer Orth #define SANITIZER_COMMON_NO_REDEFINE_BUILTINS
17*474d35f2SRainer Orth 
189642e337SNico Weber #include "safestack_platform.h"
199642e337SNico Weber #include "safestack_util.h"
20*474d35f2SRainer Orth #include "sanitizer_common/sanitizer_internal_defs.h"
219642e337SNico Weber 
229642e337SNico Weber #include <errno.h>
23*474d35f2SRainer Orth #include <string.h>
249642e337SNico Weber #include <sys/resource.h>
259642e337SNico Weber 
269642e337SNico Weber #include "interception/interception.h"
279642e337SNico Weber 
28*474d35f2SRainer Orth // interception.h drags in sanitizer_redefine_builtins.h, which in turn
29*474d35f2SRainer Orth // creates references to __sanitizer_internal_memcpy etc.  The interceptors
30*474d35f2SRainer Orth // aren't needed here, so just forward to libc.
31*474d35f2SRainer Orth extern "C" {
32*474d35f2SRainer Orth SANITIZER_INTERFACE_ATTRIBUTE void *__sanitizer_internal_memcpy(void *dest,
33*474d35f2SRainer Orth                                                                 const void *src,
34*474d35f2SRainer Orth                                                                 size_t n) {
35*474d35f2SRainer Orth   return memcpy(dest, src, n);
36*474d35f2SRainer Orth }
37*474d35f2SRainer Orth 
38*474d35f2SRainer Orth SANITIZER_INTERFACE_ATTRIBUTE void *__sanitizer_internal_memmove(
39*474d35f2SRainer Orth     void *dest, const void *src, size_t n) {
40*474d35f2SRainer Orth   return memmove(dest, src, n);
41*474d35f2SRainer Orth }
42*474d35f2SRainer Orth 
43*474d35f2SRainer Orth SANITIZER_INTERFACE_ATTRIBUTE void *__sanitizer_internal_memset(void *s, int c,
44*474d35f2SRainer Orth                                                                 size_t n) {
45*474d35f2SRainer Orth   return memset(s, c, n);
46*474d35f2SRainer Orth }
47*474d35f2SRainer Orth }  // extern "C"
48*474d35f2SRainer Orth 
499642e337SNico Weber using namespace safestack;
509642e337SNico Weber 
519642e337SNico Weber // TODO: To make accessing the unsafe stack pointer faster, we plan to
529642e337SNico Weber // eventually store it directly in the thread control block data structure on
539642e337SNico Weber // platforms where this structure is pointed to by %fs or %gs. This is exactly
549642e337SNico Weber // the same mechanism as currently being used by the traditional stack
559642e337SNico Weber // protector pass to store the stack guard (see getStackCookieLocation()
569642e337SNico Weber // function above). Doing so requires changing the tcbhead_t struct in glibc
579642e337SNico Weber // on Linux and tcb struct in libc on FreeBSD.
589642e337SNico Weber //
599642e337SNico Weber // For now, store it in a thread-local variable.
609642e337SNico Weber extern "C" {
619642e337SNico Weber __attribute__((visibility(
629642e337SNico Weber     "default"))) __thread void *__safestack_unsafe_stack_ptr = nullptr;
639642e337SNico Weber }
649642e337SNico Weber 
659642e337SNico Weber namespace {
669642e337SNico Weber 
679642e337SNico Weber // TODO: The runtime library does not currently protect the safe stack beyond
689642e337SNico Weber // relying on the system-enforced ASLR. The protection of the (safe) stack can
699642e337SNico Weber // be provided by three alternative features:
709642e337SNico Weber //
719642e337SNico Weber // 1) Protection via hardware segmentation on x86-32 and some x86-64
729642e337SNico Weber // architectures: the (safe) stack segment (implicitly accessed via the %ss
739642e337SNico Weber // segment register) can be separated from the data segment (implicitly
749642e337SNico Weber // accessed via the %ds segment register). Dereferencing a pointer to the safe
759642e337SNico Weber // segment would result in a segmentation fault.
769642e337SNico Weber //
779642e337SNico Weber // 2) Protection via software fault isolation: memory writes that are not meant
789642e337SNico Weber // to access the safe stack can be prevented from doing so through runtime
799642e337SNico Weber // instrumentation. One way to do it is to allocate the safe stack(s) in the
809642e337SNico Weber // upper half of the userspace and bitmask the corresponding upper bit of the
819642e337SNico Weber // memory addresses of memory writes that are not meant to access the safe
829642e337SNico Weber // stack.
839642e337SNico Weber //
849642e337SNico Weber // 3) Protection via information hiding on 64 bit architectures: the location
859642e337SNico Weber // of the safe stack(s) can be randomized through secure mechanisms, and the
869642e337SNico Weber // leakage of the stack pointer can be prevented. Currently, libc can leak the
879642e337SNico Weber // stack pointer in several ways (e.g. in longjmp, signal handling, user-level
889642e337SNico Weber // context switching related functions, etc.). These can be fixed in libc and
899642e337SNico Weber // in other low-level libraries, by either eliminating the escaping/dumping of
909642e337SNico Weber // the stack pointer (i.e., %rsp) when that's possible, or by using
919642e337SNico Weber // encryption/PTR_MANGLE (XOR-ing the dumped stack pointer with another secret
929642e337SNico Weber // we control and protect better, as is already done for setjmp in glibc.)
939642e337SNico Weber // Furthermore, a static machine code level verifier can be ran after code
949642e337SNico Weber // generation to make sure that the stack pointer is never written to memory,
959642e337SNico Weber // or if it is, its written on the safe stack.
969642e337SNico Weber //
979642e337SNico Weber // Finally, while the Unsafe Stack pointer is currently stored in a thread
989642e337SNico Weber // local variable, with libc support it could be stored in the TCB (thread
999642e337SNico Weber // control block) as well, eliminating another level of indirection and making
1009642e337SNico Weber // such accesses faster. Alternatively, dedicating a separate register for
1019642e337SNico Weber // storing it would also be possible.
1029642e337SNico Weber 
1039642e337SNico Weber /// Minimum stack alignment for the unsafe stack.
1049642e337SNico Weber const unsigned kStackAlign = 16;
1059642e337SNico Weber 
1069642e337SNico Weber /// Default size of the unsafe stack. This value is only used if the stack
1079642e337SNico Weber /// size rlimit is set to infinity.
1089642e337SNico Weber const unsigned kDefaultUnsafeStackSize = 0x2800000;
1099642e337SNico Weber 
1109642e337SNico Weber // Per-thread unsafe stack information. It's not frequently accessed, so there
1119642e337SNico Weber // it can be kept out of the tcb in normal thread-local variables.
1129642e337SNico Weber __thread void *unsafe_stack_start = nullptr;
1139642e337SNico Weber __thread size_t unsafe_stack_size = 0;
1149642e337SNico Weber __thread size_t unsafe_stack_guard = 0;
1159642e337SNico Weber 
1169642e337SNico Weber inline void *unsafe_stack_alloc(size_t size, size_t guard) {
1179642e337SNico Weber   SFS_CHECK(size + guard >= size);
1189642e337SNico Weber   void *addr = Mmap(nullptr, size + guard, PROT_READ | PROT_WRITE,
1199642e337SNico Weber                     MAP_PRIVATE | MAP_ANON, -1, 0);
1209642e337SNico Weber   SFS_CHECK(MAP_FAILED != addr);
1219642e337SNico Weber   Mprotect(addr, guard, PROT_NONE);
1229642e337SNico Weber   return (char *)addr + guard;
1239642e337SNico Weber }
1249642e337SNico Weber 
1259642e337SNico Weber inline void unsafe_stack_setup(void *start, size_t size, size_t guard) {
1269642e337SNico Weber   SFS_CHECK((char *)start + size >= (char *)start);
1279642e337SNico Weber   SFS_CHECK((char *)start + guard >= (char *)start);
1289642e337SNico Weber   void *stack_ptr = (char *)start + size;
1299642e337SNico Weber   SFS_CHECK((((size_t)stack_ptr) & (kStackAlign - 1)) == 0);
1309642e337SNico Weber 
1319642e337SNico Weber   __safestack_unsafe_stack_ptr = stack_ptr;
1329642e337SNico Weber   unsafe_stack_start = start;
1339642e337SNico Weber   unsafe_stack_size = size;
1349642e337SNico Weber   unsafe_stack_guard = guard;
1359642e337SNico Weber }
1369642e337SNico Weber 
1379642e337SNico Weber /// Thread data for the cleanup handler
1389642e337SNico Weber pthread_key_t thread_cleanup_key;
1399642e337SNico Weber 
1409642e337SNico Weber /// Safe stack per-thread information passed to the thread_start function
1419642e337SNico Weber struct tinfo {
1429642e337SNico Weber   void *(*start_routine)(void *);
1439642e337SNico Weber   void *start_routine_arg;
1449642e337SNico Weber 
1459642e337SNico Weber   void *unsafe_stack_start;
1469642e337SNico Weber   size_t unsafe_stack_size;
1479642e337SNico Weber   size_t unsafe_stack_guard;
1489642e337SNico Weber };
1499642e337SNico Weber 
1509642e337SNico Weber /// Wrap the thread function in order to deallocate the unsafe stack when the
1519642e337SNico Weber /// thread terminates by returning from its main function.
1529642e337SNico Weber void *thread_start(void *arg) {
1539642e337SNico Weber   struct tinfo *tinfo = (struct tinfo *)arg;
1549642e337SNico Weber 
1559642e337SNico Weber   void *(*start_routine)(void *) = tinfo->start_routine;
1569642e337SNico Weber   void *start_routine_arg = tinfo->start_routine_arg;
1579642e337SNico Weber 
1589642e337SNico Weber   // Setup the unsafe stack; this will destroy tinfo content
1599642e337SNico Weber   unsafe_stack_setup(tinfo->unsafe_stack_start, tinfo->unsafe_stack_size,
1609642e337SNico Weber                      tinfo->unsafe_stack_guard);
1619642e337SNico Weber 
1629642e337SNico Weber   // Make sure out thread-specific destructor will be called
1639642e337SNico Weber   pthread_setspecific(thread_cleanup_key, (void *)1);
1649642e337SNico Weber 
1659642e337SNico Weber   return start_routine(start_routine_arg);
1669642e337SNico Weber }
1679642e337SNico Weber 
1689642e337SNico Weber /// Linked list used to store exiting threads stack/thread information.
1699642e337SNico Weber struct thread_stack_ll {
1709642e337SNico Weber   struct thread_stack_ll *next;
1719642e337SNico Weber   void *stack_base;
1729642e337SNico Weber   size_t size;
1739642e337SNico Weber   pid_t pid;
1749642e337SNico Weber   ThreadId tid;
1759642e337SNico Weber };
1769642e337SNico Weber 
1779642e337SNico Weber /// Linked list of unsafe stacks for threads that are exiting. We delay
1789642e337SNico Weber /// unmapping them until the thread exits.
1799642e337SNico Weber thread_stack_ll *thread_stacks = nullptr;
1809642e337SNico Weber pthread_mutex_t thread_stacks_mutex = PTHREAD_MUTEX_INITIALIZER;
1819642e337SNico Weber 
1829642e337SNico Weber /// Thread-specific data destructor. We want to free the unsafe stack only after
1839642e337SNico Weber /// this thread is terminated. libc can call functions in safestack-instrumented
1849642e337SNico Weber /// code (like free) after thread-specific data destructors have run.
1859642e337SNico Weber void thread_cleanup_handler(void *_iter) {
1869642e337SNico Weber   SFS_CHECK(unsafe_stack_start != nullptr);
1879642e337SNico Weber   pthread_setspecific(thread_cleanup_key, NULL);
1889642e337SNico Weber 
1899642e337SNico Weber   pthread_mutex_lock(&thread_stacks_mutex);
1909642e337SNico Weber   // Temporary list to hold the previous threads stacks so we don't hold the
1919642e337SNico Weber   // thread_stacks_mutex for long.
1929642e337SNico Weber   thread_stack_ll *temp_stacks = thread_stacks;
1939642e337SNico Weber   thread_stacks = nullptr;
1949642e337SNico Weber   pthread_mutex_unlock(&thread_stacks_mutex);
1959642e337SNico Weber 
1969642e337SNico Weber   pid_t pid = getpid();
1979642e337SNico Weber   ThreadId tid = GetTid();
1989642e337SNico Weber 
1999642e337SNico Weber   // Free stacks for dead threads
2009642e337SNico Weber   thread_stack_ll **stackp = &temp_stacks;
2019642e337SNico Weber   while (*stackp) {
2029642e337SNico Weber     thread_stack_ll *stack = *stackp;
2039642e337SNico Weber     if (stack->pid != pid ||
2049642e337SNico Weber         (-1 == TgKill(stack->pid, stack->tid, 0) && errno == ESRCH)) {
2059642e337SNico Weber       Munmap(stack->stack_base, stack->size);
2069642e337SNico Weber       *stackp = stack->next;
2079642e337SNico Weber       free(stack);
2089642e337SNico Weber     } else
2099642e337SNico Weber       stackp = &stack->next;
2109642e337SNico Weber   }
2119642e337SNico Weber 
2129642e337SNico Weber   thread_stack_ll *cur_stack =
2139642e337SNico Weber       (thread_stack_ll *)malloc(sizeof(thread_stack_ll));
2149642e337SNico Weber   cur_stack->stack_base = (char *)unsafe_stack_start - unsafe_stack_guard;
2159642e337SNico Weber   cur_stack->size = unsafe_stack_size + unsafe_stack_guard;
2169642e337SNico Weber   cur_stack->pid = pid;
2179642e337SNico Weber   cur_stack->tid = tid;
2189642e337SNico Weber 
2199642e337SNico Weber   pthread_mutex_lock(&thread_stacks_mutex);
2209642e337SNico Weber   // Merge thread_stacks with the current thread's stack and any remaining
2219642e337SNico Weber   // temp_stacks
2229642e337SNico Weber   *stackp = thread_stacks;
2239642e337SNico Weber   cur_stack->next = temp_stacks;
2249642e337SNico Weber   thread_stacks = cur_stack;
2259642e337SNico Weber   pthread_mutex_unlock(&thread_stacks_mutex);
2269642e337SNico Weber 
2279642e337SNico Weber   unsafe_stack_start = nullptr;
2289642e337SNico Weber }
2299642e337SNico Weber 
2309642e337SNico Weber void EnsureInterceptorsInitialized();
2319642e337SNico Weber 
2329642e337SNico Weber /// Intercept thread creation operation to allocate and setup the unsafe stack
2339642e337SNico Weber INTERCEPTOR(int, pthread_create, pthread_t *thread,
2349642e337SNico Weber             const pthread_attr_t *attr,
2359642e337SNico Weber             void *(*start_routine)(void*), void *arg) {
2369642e337SNico Weber   EnsureInterceptorsInitialized();
2379642e337SNico Weber   size_t size = 0;
2389642e337SNico Weber   size_t guard = 0;
2399642e337SNico Weber 
2409642e337SNico Weber   if (attr) {
2419642e337SNico Weber     pthread_attr_getstacksize(attr, &size);
2429642e337SNico Weber     pthread_attr_getguardsize(attr, &guard);
2439642e337SNico Weber   } else {
2449642e337SNico Weber     // get pthread default stack size
2459642e337SNico Weber     pthread_attr_t tmpattr;
2469642e337SNico Weber     pthread_attr_init(&tmpattr);
2479642e337SNico Weber     pthread_attr_getstacksize(&tmpattr, &size);
2489642e337SNico Weber     pthread_attr_getguardsize(&tmpattr, &guard);
2499642e337SNico Weber     pthread_attr_destroy(&tmpattr);
2509642e337SNico Weber   }
2519642e337SNico Weber 
252*474d35f2SRainer Orth #if SANITIZER_SOLARIS
253*474d35f2SRainer Orth   // Solaris pthread_attr_init initializes stacksize to 0 (the default), so
254*474d35f2SRainer Orth   // hardcode the actual values as documented in pthread_create(3C).
255*474d35f2SRainer Orth   if (size == 0)
256*474d35f2SRainer Orth #  if defined(_LP64)
257*474d35f2SRainer Orth     size = 2 * 1024 * 1024;
258*474d35f2SRainer Orth #  else
259*474d35f2SRainer Orth     size = 1024 * 1024;
260*474d35f2SRainer Orth #  endif
261*474d35f2SRainer Orth #endif
262*474d35f2SRainer Orth 
2639642e337SNico Weber   SFS_CHECK(size);
2649642e337SNico Weber   size = RoundUpTo(size, kStackAlign);
2659642e337SNico Weber 
2669642e337SNico Weber   void *addr = unsafe_stack_alloc(size, guard);
2679642e337SNico Weber   // Put tinfo at the end of the buffer. guard may be not page aligned.
2689642e337SNico Weber   // If that is so then some bytes after addr can be mprotected.
2699642e337SNico Weber   struct tinfo *tinfo =
2709642e337SNico Weber       (struct tinfo *)(((char *)addr) + size - sizeof(struct tinfo));
2719642e337SNico Weber   tinfo->start_routine = start_routine;
2729642e337SNico Weber   tinfo->start_routine_arg = arg;
2739642e337SNico Weber   tinfo->unsafe_stack_start = addr;
2749642e337SNico Weber   tinfo->unsafe_stack_size = size;
2759642e337SNico Weber   tinfo->unsafe_stack_guard = guard;
2769642e337SNico Weber 
2779642e337SNico Weber   return REAL(pthread_create)(thread, attr, thread_start, tinfo);
2789642e337SNico Weber }
2799642e337SNico Weber 
2809642e337SNico Weber pthread_mutex_t interceptor_init_mutex = PTHREAD_MUTEX_INITIALIZER;
2819642e337SNico Weber bool interceptors_inited = false;
2829642e337SNico Weber 
2839642e337SNico Weber void EnsureInterceptorsInitialized() {
2849642e337SNico Weber   MutexLock lock(interceptor_init_mutex);
2859642e337SNico Weber   if (interceptors_inited)
2869642e337SNico Weber     return;
2879642e337SNico Weber 
2889642e337SNico Weber   // Initialize pthread interceptors for thread allocation
2899642e337SNico Weber   INTERCEPT_FUNCTION(pthread_create);
2909642e337SNico Weber 
2919642e337SNico Weber   interceptors_inited = true;
2929642e337SNico Weber }
2939642e337SNico Weber 
2949642e337SNico Weber }  // namespace
2959642e337SNico Weber 
2969642e337SNico Weber extern "C" __attribute__((visibility("default")))
2979642e337SNico Weber #if !SANITIZER_CAN_USE_PREINIT_ARRAY
2989642e337SNico Weber // On ELF platforms, the constructor is invoked using .preinit_array (see below)
2999642e337SNico Weber __attribute__((constructor(0)))
3009642e337SNico Weber #endif
3019642e337SNico Weber void __safestack_init() {
3029642e337SNico Weber   // Determine the stack size for the main thread.
3039642e337SNico Weber   size_t size = kDefaultUnsafeStackSize;
3049642e337SNico Weber   size_t guard = 4096;
3059642e337SNico Weber 
3069642e337SNico Weber   struct rlimit limit;
3079642e337SNico Weber   if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur != RLIM_INFINITY)
3089642e337SNico Weber     size = limit.rlim_cur;
3099642e337SNico Weber 
3109642e337SNico Weber   // Allocate unsafe stack for main thread
3119642e337SNico Weber   void *addr = unsafe_stack_alloc(size, guard);
3129642e337SNico Weber   unsafe_stack_setup(addr, size, guard);
3139642e337SNico Weber 
3149642e337SNico Weber   // Setup the cleanup handler
3159642e337SNico Weber   pthread_key_create(&thread_cleanup_key, thread_cleanup_handler);
3169642e337SNico Weber }
3179642e337SNico Weber 
3189642e337SNico Weber #if SANITIZER_CAN_USE_PREINIT_ARRAY
3199642e337SNico Weber // On ELF platforms, run safestack initialization before any other constructors.
3209642e337SNico Weber // On other platforms we use the constructor attribute to arrange to run our
3219642e337SNico Weber // initialization early.
3229642e337SNico Weber extern "C" {
3239642e337SNico Weber __attribute__((section(".preinit_array"),
3249642e337SNico Weber                used)) void (*__safestack_preinit)(void) = __safestack_init;
3259642e337SNico Weber }
3269642e337SNico Weber #endif
3279642e337SNico Weber 
3289642e337SNico Weber extern "C"
3299642e337SNico Weber     __attribute__((visibility("default"))) void *__get_unsafe_stack_bottom() {
3309642e337SNico Weber   return unsafe_stack_start;
3319642e337SNico Weber }
3329642e337SNico Weber 
3339642e337SNico Weber extern "C"
3349642e337SNico Weber     __attribute__((visibility("default"))) void *__get_unsafe_stack_top() {
3359642e337SNico Weber   return (char*)unsafe_stack_start + unsafe_stack_size;
3369642e337SNico Weber }
3379642e337SNico Weber 
3389642e337SNico Weber extern "C"
3399642e337SNico Weber     __attribute__((visibility("default"))) void *__get_unsafe_stack_start() {
3409642e337SNico Weber   return unsafe_stack_start;
3419642e337SNico Weber }
3429642e337SNico Weber 
3439642e337SNico Weber extern "C"
3449642e337SNico Weber     __attribute__((visibility("default"))) void *__get_unsafe_stack_ptr() {
3459642e337SNico Weber   return __safestack_unsafe_stack_ptr;
3469642e337SNico Weber }
347