1353944Sdim//===-- safestack.cpp -----------------------------------------------------===// 2353944Sdim// 3353944Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353944Sdim// See https://llvm.org/LICENSE.txt for license information. 5353944Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6353944Sdim// 7353944Sdim//===----------------------------------------------------------------------===// 8353944Sdim// 9353944Sdim// This file implements the runtime support for the safe stack protection 10353944Sdim// mechanism. The runtime manages allocation/deallocation of the unsafe stack 11353944Sdim// for the main thread, as well as all pthreads that are created/destroyed 12353944Sdim// during program execution. 13353944Sdim// 14353944Sdim//===----------------------------------------------------------------------===// 15353944Sdim 16353944Sdim#include "safestack_platform.h" 17353944Sdim#include "safestack_util.h" 18353944Sdim 19353944Sdim#include <errno.h> 20353944Sdim#include <sys/resource.h> 21353944Sdim 22353944Sdim#include "interception/interception.h" 23353944Sdim 24353944Sdimusing namespace safestack; 25353944Sdim 26353944Sdim// TODO: To make accessing the unsafe stack pointer faster, we plan to 27353944Sdim// eventually store it directly in the thread control block data structure on 28353944Sdim// platforms where this structure is pointed to by %fs or %gs. This is exactly 29353944Sdim// the same mechanism as currently being used by the traditional stack 30353944Sdim// protector pass to store the stack guard (see getStackCookieLocation() 31353944Sdim// function above). Doing so requires changing the tcbhead_t struct in glibc 32353944Sdim// on Linux and tcb struct in libc on FreeBSD. 33353944Sdim// 34353944Sdim// For now, store it in a thread-local variable. 35353944Sdimextern "C" { 36353944Sdim__attribute__((visibility( 37353944Sdim "default"))) __thread void *__safestack_unsafe_stack_ptr = nullptr; 38353944Sdim} 39353944Sdim 40353944Sdimnamespace { 41353944Sdim 42353944Sdim// TODO: The runtime library does not currently protect the safe stack beyond 43353944Sdim// relying on the system-enforced ASLR. The protection of the (safe) stack can 44353944Sdim// be provided by three alternative features: 45353944Sdim// 46353944Sdim// 1) Protection via hardware segmentation on x86-32 and some x86-64 47353944Sdim// architectures: the (safe) stack segment (implicitly accessed via the %ss 48353944Sdim// segment register) can be separated from the data segment (implicitly 49353944Sdim// accessed via the %ds segment register). Dereferencing a pointer to the safe 50353944Sdim// segment would result in a segmentation fault. 51353944Sdim// 52353944Sdim// 2) Protection via software fault isolation: memory writes that are not meant 53353944Sdim// to access the safe stack can be prevented from doing so through runtime 54353944Sdim// instrumentation. One way to do it is to allocate the safe stack(s) in the 55353944Sdim// upper half of the userspace and bitmask the corresponding upper bit of the 56353944Sdim// memory addresses of memory writes that are not meant to access the safe 57353944Sdim// stack. 58353944Sdim// 59353944Sdim// 3) Protection via information hiding on 64 bit architectures: the location 60353944Sdim// of the safe stack(s) can be randomized through secure mechanisms, and the 61353944Sdim// leakage of the stack pointer can be prevented. Currently, libc can leak the 62353944Sdim// stack pointer in several ways (e.g. in longjmp, signal handling, user-level 63353944Sdim// context switching related functions, etc.). These can be fixed in libc and 64353944Sdim// in other low-level libraries, by either eliminating the escaping/dumping of 65353944Sdim// the stack pointer (i.e., %rsp) when that's possible, or by using 66353944Sdim// encryption/PTR_MANGLE (XOR-ing the dumped stack pointer with another secret 67353944Sdim// we control and protect better, as is already done for setjmp in glibc.) 68353944Sdim// Furthermore, a static machine code level verifier can be ran after code 69353944Sdim// generation to make sure that the stack pointer is never written to memory, 70353944Sdim// or if it is, its written on the safe stack. 71353944Sdim// 72353944Sdim// Finally, while the Unsafe Stack pointer is currently stored in a thread 73353944Sdim// local variable, with libc support it could be stored in the TCB (thread 74353944Sdim// control block) as well, eliminating another level of indirection and making 75353944Sdim// such accesses faster. Alternatively, dedicating a separate register for 76353944Sdim// storing it would also be possible. 77353944Sdim 78353944Sdim/// Minimum stack alignment for the unsafe stack. 79353944Sdimconst unsigned kStackAlign = 16; 80353944Sdim 81353944Sdim/// Default size of the unsafe stack. This value is only used if the stack 82353944Sdim/// size rlimit is set to infinity. 83353944Sdimconst unsigned kDefaultUnsafeStackSize = 0x2800000; 84353944Sdim 85353944Sdim// Per-thread unsafe stack information. It's not frequently accessed, so there 86353944Sdim// it can be kept out of the tcb in normal thread-local variables. 87353944Sdim__thread void *unsafe_stack_start = nullptr; 88353944Sdim__thread size_t unsafe_stack_size = 0; 89353944Sdim__thread size_t unsafe_stack_guard = 0; 90353944Sdim 91353944Sdiminline void *unsafe_stack_alloc(size_t size, size_t guard) { 92353944Sdim SFS_CHECK(size + guard >= size); 93353944Sdim void *addr = Mmap(nullptr, size + guard, PROT_READ | PROT_WRITE, 94353944Sdim MAP_PRIVATE | MAP_ANON, -1, 0); 95353944Sdim SFS_CHECK(MAP_FAILED != addr); 96353944Sdim Mprotect(addr, guard, PROT_NONE); 97353944Sdim return (char *)addr + guard; 98353944Sdim} 99353944Sdim 100353944Sdiminline void unsafe_stack_setup(void *start, size_t size, size_t guard) { 101353944Sdim SFS_CHECK((char *)start + size >= (char *)start); 102353944Sdim SFS_CHECK((char *)start + guard >= (char *)start); 103353944Sdim void *stack_ptr = (char *)start + size; 104353944Sdim SFS_CHECK((((size_t)stack_ptr) & (kStackAlign - 1)) == 0); 105353944Sdim 106353944Sdim __safestack_unsafe_stack_ptr = stack_ptr; 107353944Sdim unsafe_stack_start = start; 108353944Sdim unsafe_stack_size = size; 109353944Sdim unsafe_stack_guard = guard; 110353944Sdim} 111353944Sdim 112353944Sdim/// Thread data for the cleanup handler 113353944Sdimpthread_key_t thread_cleanup_key; 114353944Sdim 115353944Sdim/// Safe stack per-thread information passed to the thread_start function 116353944Sdimstruct tinfo { 117353944Sdim void *(*start_routine)(void *); 118353944Sdim void *start_routine_arg; 119353944Sdim 120353944Sdim void *unsafe_stack_start; 121353944Sdim size_t unsafe_stack_size; 122353944Sdim size_t unsafe_stack_guard; 123353944Sdim}; 124353944Sdim 125353944Sdim/// Wrap the thread function in order to deallocate the unsafe stack when the 126353944Sdim/// thread terminates by returning from its main function. 127353944Sdimvoid *thread_start(void *arg) { 128353944Sdim struct tinfo *tinfo = (struct tinfo *)arg; 129353944Sdim 130353944Sdim void *(*start_routine)(void *) = tinfo->start_routine; 131353944Sdim void *start_routine_arg = tinfo->start_routine_arg; 132353944Sdim 133353944Sdim // Setup the unsafe stack; this will destroy tinfo content 134353944Sdim unsafe_stack_setup(tinfo->unsafe_stack_start, tinfo->unsafe_stack_size, 135353944Sdim tinfo->unsafe_stack_guard); 136353944Sdim 137353944Sdim // Make sure out thread-specific destructor will be called 138353944Sdim pthread_setspecific(thread_cleanup_key, (void *)1); 139353944Sdim 140353944Sdim return start_routine(start_routine_arg); 141353944Sdim} 142353944Sdim 143353944Sdim/// Linked list used to store exiting threads stack/thread information. 144353944Sdimstruct thread_stack_ll { 145353944Sdim struct thread_stack_ll *next; 146353944Sdim void *stack_base; 147353944Sdim size_t size; 148353944Sdim pid_t pid; 149353944Sdim ThreadId tid; 150353944Sdim}; 151353944Sdim 152353944Sdim/// Linked list of unsafe stacks for threads that are exiting. We delay 153353944Sdim/// unmapping them until the thread exits. 154353944Sdimthread_stack_ll *thread_stacks = nullptr; 155353944Sdimpthread_mutex_t thread_stacks_mutex = PTHREAD_MUTEX_INITIALIZER; 156353944Sdim 157353944Sdim/// Thread-specific data destructor. We want to free the unsafe stack only after 158353944Sdim/// this thread is terminated. libc can call functions in safestack-instrumented 159353944Sdim/// code (like free) after thread-specific data destructors have run. 160353944Sdimvoid thread_cleanup_handler(void *_iter) { 161353944Sdim SFS_CHECK(unsafe_stack_start != nullptr); 162353944Sdim pthread_setspecific(thread_cleanup_key, NULL); 163353944Sdim 164353944Sdim pthread_mutex_lock(&thread_stacks_mutex); 165353944Sdim // Temporary list to hold the previous threads stacks so we don't hold the 166353944Sdim // thread_stacks_mutex for long. 167353944Sdim thread_stack_ll *temp_stacks = thread_stacks; 168353944Sdim thread_stacks = nullptr; 169353944Sdim pthread_mutex_unlock(&thread_stacks_mutex); 170353944Sdim 171353944Sdim pid_t pid = getpid(); 172353944Sdim ThreadId tid = GetTid(); 173353944Sdim 174353944Sdim // Free stacks for dead threads 175353944Sdim thread_stack_ll **stackp = &temp_stacks; 176353944Sdim while (*stackp) { 177353944Sdim thread_stack_ll *stack = *stackp; 178353944Sdim if (stack->pid != pid || 179353944Sdim (-1 == TgKill(stack->pid, stack->tid, 0) && errno == ESRCH)) { 180353944Sdim Munmap(stack->stack_base, stack->size); 181353944Sdim *stackp = stack->next; 182353944Sdim free(stack); 183353944Sdim } else 184353944Sdim stackp = &stack->next; 185353944Sdim } 186353944Sdim 187353944Sdim thread_stack_ll *cur_stack = 188353944Sdim (thread_stack_ll *)malloc(sizeof(thread_stack_ll)); 189353944Sdim cur_stack->stack_base = (char *)unsafe_stack_start - unsafe_stack_guard; 190353944Sdim cur_stack->size = unsafe_stack_size + unsafe_stack_guard; 191353944Sdim cur_stack->pid = pid; 192353944Sdim cur_stack->tid = tid; 193353944Sdim 194353944Sdim pthread_mutex_lock(&thread_stacks_mutex); 195353944Sdim // Merge thread_stacks with the current thread's stack and any remaining 196353944Sdim // temp_stacks 197353944Sdim *stackp = thread_stacks; 198353944Sdim cur_stack->next = temp_stacks; 199353944Sdim thread_stacks = cur_stack; 200353944Sdim pthread_mutex_unlock(&thread_stacks_mutex); 201353944Sdim 202353944Sdim unsafe_stack_start = nullptr; 203353944Sdim} 204353944Sdim 205353944Sdimvoid EnsureInterceptorsInitialized(); 206353944Sdim 207353944Sdim/// Intercept thread creation operation to allocate and setup the unsafe stack 208353944SdimINTERCEPTOR(int, pthread_create, pthread_t *thread, 209353944Sdim const pthread_attr_t *attr, 210353944Sdim void *(*start_routine)(void*), void *arg) { 211353944Sdim EnsureInterceptorsInitialized(); 212353944Sdim size_t size = 0; 213353944Sdim size_t guard = 0; 214353944Sdim 215353944Sdim if (attr) { 216353944Sdim pthread_attr_getstacksize(attr, &size); 217353944Sdim pthread_attr_getguardsize(attr, &guard); 218353944Sdim } else { 219353944Sdim // get pthread default stack size 220353944Sdim pthread_attr_t tmpattr; 221353944Sdim pthread_attr_init(&tmpattr); 222353944Sdim pthread_attr_getstacksize(&tmpattr, &size); 223353944Sdim pthread_attr_getguardsize(&tmpattr, &guard); 224353944Sdim pthread_attr_destroy(&tmpattr); 225353944Sdim } 226353944Sdim 227353944Sdim SFS_CHECK(size); 228353944Sdim size = RoundUpTo(size, kStackAlign); 229353944Sdim 230353944Sdim void *addr = unsafe_stack_alloc(size, guard); 231353944Sdim // Put tinfo at the end of the buffer. guard may be not page aligned. 232353944Sdim // If that is so then some bytes after addr can be mprotected. 233353944Sdim struct tinfo *tinfo = 234353944Sdim (struct tinfo *)(((char *)addr) + size - sizeof(struct tinfo)); 235353944Sdim tinfo->start_routine = start_routine; 236353944Sdim tinfo->start_routine_arg = arg; 237353944Sdim tinfo->unsafe_stack_start = addr; 238353944Sdim tinfo->unsafe_stack_size = size; 239353944Sdim tinfo->unsafe_stack_guard = guard; 240353944Sdim 241353944Sdim return REAL(pthread_create)(thread, attr, thread_start, tinfo); 242353944Sdim} 243353944Sdim 244353944Sdimpthread_mutex_t interceptor_init_mutex = PTHREAD_MUTEX_INITIALIZER; 245353944Sdimbool interceptors_inited = false; 246353944Sdim 247353944Sdimvoid EnsureInterceptorsInitialized() { 248353944Sdim MutexLock lock(interceptor_init_mutex); 249353944Sdim if (interceptors_inited) 250353944Sdim return; 251353944Sdim 252353944Sdim // Initialize pthread interceptors for thread allocation 253353944Sdim INTERCEPT_FUNCTION(pthread_create); 254353944Sdim 255353944Sdim interceptors_inited = true; 256353944Sdim} 257353944Sdim 258353944Sdim} // namespace 259353944Sdim 260353944Sdimextern "C" __attribute__((visibility("default"))) 261353944Sdim#if !SANITIZER_CAN_USE_PREINIT_ARRAY 262353944Sdim// On ELF platforms, the constructor is invoked using .preinit_array (see below) 263353944Sdim__attribute__((constructor(0))) 264353944Sdim#endif 265353944Sdimvoid __safestack_init() { 266353944Sdim // Determine the stack size for the main thread. 267353944Sdim size_t size = kDefaultUnsafeStackSize; 268353944Sdim size_t guard = 4096; 269353944Sdim 270353944Sdim struct rlimit limit; 271353944Sdim if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur != RLIM_INFINITY) 272353944Sdim size = limit.rlim_cur; 273353944Sdim 274353944Sdim // Allocate unsafe stack for main thread 275353944Sdim void *addr = unsafe_stack_alloc(size, guard); 276353944Sdim unsafe_stack_setup(addr, size, guard); 277353944Sdim 278353944Sdim // Setup the cleanup handler 279353944Sdim pthread_key_create(&thread_cleanup_key, thread_cleanup_handler); 280353944Sdim} 281353944Sdim 282353944Sdim#if SANITIZER_CAN_USE_PREINIT_ARRAY 283353944Sdim// On ELF platforms, run safestack initialization before any other constructors. 284353944Sdim// On other platforms we use the constructor attribute to arrange to run our 285353944Sdim// initialization early. 286353944Sdimextern "C" { 287353944Sdim__attribute__((section(".preinit_array"), 288353944Sdim used)) void (*__safestack_preinit)(void) = __safestack_init; 289353944Sdim} 290353944Sdim#endif 291353944Sdim 292353944Sdimextern "C" 293353944Sdim __attribute__((visibility("default"))) void *__get_unsafe_stack_bottom() { 294353944Sdim return unsafe_stack_start; 295353944Sdim} 296353944Sdim 297353944Sdimextern "C" 298353944Sdim __attribute__((visibility("default"))) void *__get_unsafe_stack_top() { 299353944Sdim return (char*)unsafe_stack_start + unsafe_stack_size; 300353944Sdim} 301353944Sdim 302353944Sdimextern "C" 303353944Sdim __attribute__((visibility("default"))) void *__get_unsafe_stack_start() { 304353944Sdim return unsafe_stack_start; 305353944Sdim} 306353944Sdim 307353944Sdimextern "C" 308353944Sdim __attribute__((visibility("default"))) void *__get_unsafe_stack_ptr() { 309353944Sdim return __safestack_unsafe_stack_ptr; 310353944Sdim} 311