1//===-- safestack.cpp -----------------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file implements the runtime support for the safe stack protection 10// mechanism. The runtime manages allocation/deallocation of the unsafe stack 11// for the main thread, as well as all pthreads that are created/destroyed 12// during program execution. 13// 14//===----------------------------------------------------------------------===// 15 16#include "safestack_platform.h" 17#include "safestack_util.h" 18 19#include <errno.h> 20#include <sys/resource.h> 21 22#include "interception/interception.h" 23 24using namespace safestack; 25 26// TODO: To make accessing the unsafe stack pointer faster, we plan to 27// eventually store it directly in the thread control block data structure on 28// platforms where this structure is pointed to by %fs or %gs. This is exactly 29// the same mechanism as currently being used by the traditional stack 30// protector pass to store the stack guard (see getStackCookieLocation() 31// function above). Doing so requires changing the tcbhead_t struct in glibc 32// on Linux and tcb struct in libc on FreeBSD. 33// 34// For now, store it in a thread-local variable. 35extern "C" { 36__attribute__((visibility( 37 "default"))) __thread void *__safestack_unsafe_stack_ptr = nullptr; 38} 39 40namespace { 41 42// TODO: The runtime library does not currently protect the safe stack beyond 43// relying on the system-enforced ASLR. The protection of the (safe) stack can 44// be provided by three alternative features: 45// 46// 1) Protection via hardware segmentation on x86-32 and some x86-64 47// architectures: the (safe) stack segment (implicitly accessed via the %ss 48// segment register) can be separated from the data segment (implicitly 49// accessed via the %ds segment register). Dereferencing a pointer to the safe 50// segment would result in a segmentation fault. 51// 52// 2) Protection via software fault isolation: memory writes that are not meant 53// to access the safe stack can be prevented from doing so through runtime 54// instrumentation. One way to do it is to allocate the safe stack(s) in the 55// upper half of the userspace and bitmask the corresponding upper bit of the 56// memory addresses of memory writes that are not meant to access the safe 57// stack. 58// 59// 3) Protection via information hiding on 64 bit architectures: the location 60// of the safe stack(s) can be randomized through secure mechanisms, and the 61// leakage of the stack pointer can be prevented. Currently, libc can leak the 62// stack pointer in several ways (e.g. in longjmp, signal handling, user-level 63// context switching related functions, etc.). These can be fixed in libc and 64// in other low-level libraries, by either eliminating the escaping/dumping of 65// the stack pointer (i.e., %rsp) when that's possible, or by using 66// encryption/PTR_MANGLE (XOR-ing the dumped stack pointer with another secret 67// we control and protect better, as is already done for setjmp in glibc.) 68// Furthermore, a static machine code level verifier can be ran after code 69// generation to make sure that the stack pointer is never written to memory, 70// or if it is, its written on the safe stack. 71// 72// Finally, while the Unsafe Stack pointer is currently stored in a thread 73// local variable, with libc support it could be stored in the TCB (thread 74// control block) as well, eliminating another level of indirection and making 75// such accesses faster. Alternatively, dedicating a separate register for 76// storing it would also be possible. 77 78/// Minimum stack alignment for the unsafe stack. 79const unsigned kStackAlign = 16; 80 81/// Default size of the unsafe stack. This value is only used if the stack 82/// size rlimit is set to infinity. 83const unsigned kDefaultUnsafeStackSize = 0x2800000; 84 85// Per-thread unsafe stack information. It's not frequently accessed, so there 86// it can be kept out of the tcb in normal thread-local variables. 87__thread void *unsafe_stack_start = nullptr; 88__thread size_t unsafe_stack_size = 0; 89__thread size_t unsafe_stack_guard = 0; 90 91inline void *unsafe_stack_alloc(size_t size, size_t guard) { 92 SFS_CHECK(size + guard >= size); 93 void *addr = Mmap(nullptr, size + guard, PROT_READ | PROT_WRITE, 94 MAP_PRIVATE | MAP_ANON, -1, 0); 95 SFS_CHECK(MAP_FAILED != addr); 96 Mprotect(addr, guard, PROT_NONE); 97 return (char *)addr + guard; 98} 99 100inline void unsafe_stack_setup(void *start, size_t size, size_t guard) { 101 SFS_CHECK((char *)start + size >= (char *)start); 102 SFS_CHECK((char *)start + guard >= (char *)start); 103 void *stack_ptr = (char *)start + size; 104 SFS_CHECK((((size_t)stack_ptr) & (kStackAlign - 1)) == 0); 105 106 __safestack_unsafe_stack_ptr = stack_ptr; 107 unsafe_stack_start = start; 108 unsafe_stack_size = size; 109 unsafe_stack_guard = guard; 110} 111 112/// Thread data for the cleanup handler 113pthread_key_t thread_cleanup_key; 114 115/// Safe stack per-thread information passed to the thread_start function 116struct tinfo { 117 void *(*start_routine)(void *); 118 void *start_routine_arg; 119 120 void *unsafe_stack_start; 121 size_t unsafe_stack_size; 122 size_t unsafe_stack_guard; 123}; 124 125/// Wrap the thread function in order to deallocate the unsafe stack when the 126/// thread terminates by returning from its main function. 127void *thread_start(void *arg) { 128 struct tinfo *tinfo = (struct tinfo *)arg; 129 130 void *(*start_routine)(void *) = tinfo->start_routine; 131 void *start_routine_arg = tinfo->start_routine_arg; 132 133 // Setup the unsafe stack; this will destroy tinfo content 134 unsafe_stack_setup(tinfo->unsafe_stack_start, tinfo->unsafe_stack_size, 135 tinfo->unsafe_stack_guard); 136 137 // Make sure out thread-specific destructor will be called 138 pthread_setspecific(thread_cleanup_key, (void *)1); 139 140 return start_routine(start_routine_arg); 141} 142 143/// Linked list used to store exiting threads stack/thread information. 144struct thread_stack_ll { 145 struct thread_stack_ll *next; 146 void *stack_base; 147 size_t size; 148 pid_t pid; 149 ThreadId tid; 150}; 151 152/// Linked list of unsafe stacks for threads that are exiting. We delay 153/// unmapping them until the thread exits. 154thread_stack_ll *thread_stacks = nullptr; 155pthread_mutex_t thread_stacks_mutex = PTHREAD_MUTEX_INITIALIZER; 156 157/// Thread-specific data destructor. We want to free the unsafe stack only after 158/// this thread is terminated. libc can call functions in safestack-instrumented 159/// code (like free) after thread-specific data destructors have run. 160void thread_cleanup_handler(void *_iter) { 161 SFS_CHECK(unsafe_stack_start != nullptr); 162 pthread_setspecific(thread_cleanup_key, NULL); 163 164 pthread_mutex_lock(&thread_stacks_mutex); 165 // Temporary list to hold the previous threads stacks so we don't hold the 166 // thread_stacks_mutex for long. 167 thread_stack_ll *temp_stacks = thread_stacks; 168 thread_stacks = nullptr; 169 pthread_mutex_unlock(&thread_stacks_mutex); 170 171 pid_t pid = getpid(); 172 ThreadId tid = GetTid(); 173 174 // Free stacks for dead threads 175 thread_stack_ll **stackp = &temp_stacks; 176 while (*stackp) { 177 thread_stack_ll *stack = *stackp; 178 if (stack->pid != pid || 179 (-1 == TgKill(stack->pid, stack->tid, 0) && errno == ESRCH)) { 180 Munmap(stack->stack_base, stack->size); 181 *stackp = stack->next; 182 free(stack); 183 } else 184 stackp = &stack->next; 185 } 186 187 thread_stack_ll *cur_stack = 188 (thread_stack_ll *)malloc(sizeof(thread_stack_ll)); 189 cur_stack->stack_base = (char *)unsafe_stack_start - unsafe_stack_guard; 190 cur_stack->size = unsafe_stack_size + unsafe_stack_guard; 191 cur_stack->pid = pid; 192 cur_stack->tid = tid; 193 194 pthread_mutex_lock(&thread_stacks_mutex); 195 // Merge thread_stacks with the current thread's stack and any remaining 196 // temp_stacks 197 *stackp = thread_stacks; 198 cur_stack->next = temp_stacks; 199 thread_stacks = cur_stack; 200 pthread_mutex_unlock(&thread_stacks_mutex); 201 202 unsafe_stack_start = nullptr; 203} 204 205void EnsureInterceptorsInitialized(); 206 207/// Intercept thread creation operation to allocate and setup the unsafe stack 208INTERCEPTOR(int, pthread_create, pthread_t *thread, 209 const pthread_attr_t *attr, 210 void *(*start_routine)(void*), void *arg) { 211 EnsureInterceptorsInitialized(); 212 size_t size = 0; 213 size_t guard = 0; 214 215 if (attr) { 216 pthread_attr_getstacksize(attr, &size); 217 pthread_attr_getguardsize(attr, &guard); 218 } else { 219 // get pthread default stack size 220 pthread_attr_t tmpattr; 221 pthread_attr_init(&tmpattr); 222 pthread_attr_getstacksize(&tmpattr, &size); 223 pthread_attr_getguardsize(&tmpattr, &guard); 224 pthread_attr_destroy(&tmpattr); 225 } 226 227 SFS_CHECK(size); 228 size = RoundUpTo(size, kStackAlign); 229 230 void *addr = unsafe_stack_alloc(size, guard); 231 // Put tinfo at the end of the buffer. guard may be not page aligned. 232 // If that is so then some bytes after addr can be mprotected. 233 struct tinfo *tinfo = 234 (struct tinfo *)(((char *)addr) + size - sizeof(struct tinfo)); 235 tinfo->start_routine = start_routine; 236 tinfo->start_routine_arg = arg; 237 tinfo->unsafe_stack_start = addr; 238 tinfo->unsafe_stack_size = size; 239 tinfo->unsafe_stack_guard = guard; 240 241 return REAL(pthread_create)(thread, attr, thread_start, tinfo); 242} 243 244pthread_mutex_t interceptor_init_mutex = PTHREAD_MUTEX_INITIALIZER; 245bool interceptors_inited = false; 246 247void EnsureInterceptorsInitialized() { 248 MutexLock lock(interceptor_init_mutex); 249 if (interceptors_inited) 250 return; 251 252 // Initialize pthread interceptors for thread allocation 253 INTERCEPT_FUNCTION(pthread_create); 254 255 interceptors_inited = true; 256} 257 258} // namespace 259 260extern "C" __attribute__((visibility("default"))) 261#if !SANITIZER_CAN_USE_PREINIT_ARRAY 262// On ELF platforms, the constructor is invoked using .preinit_array (see below) 263__attribute__((constructor(0))) 264#endif 265void __safestack_init() { 266 // Determine the stack size for the main thread. 267 size_t size = kDefaultUnsafeStackSize; 268 size_t guard = 4096; 269 270 struct rlimit limit; 271 if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur != RLIM_INFINITY) 272 size = limit.rlim_cur; 273 274 // Allocate unsafe stack for main thread 275 void *addr = unsafe_stack_alloc(size, guard); 276 unsafe_stack_setup(addr, size, guard); 277 278 // Setup the cleanup handler 279 pthread_key_create(&thread_cleanup_key, thread_cleanup_handler); 280} 281 282#if SANITIZER_CAN_USE_PREINIT_ARRAY 283// On ELF platforms, run safestack initialization before any other constructors. 284// On other platforms we use the constructor attribute to arrange to run our 285// initialization early. 286extern "C" { 287__attribute__((section(".preinit_array"), 288 used)) void (*__safestack_preinit)(void) = __safestack_init; 289} 290#endif 291 292extern "C" 293 __attribute__((visibility("default"))) void *__get_unsafe_stack_bottom() { 294 return unsafe_stack_start; 295} 296 297extern "C" 298 __attribute__((visibility("default"))) void *__get_unsafe_stack_top() { 299 return (char*)unsafe_stack_start + unsafe_stack_size; 300} 301 302extern "C" 303 __attribute__((visibility("default"))) void *__get_unsafe_stack_start() { 304 return unsafe_stack_start; 305} 306 307extern "C" 308 __attribute__((visibility("default"))) void *__get_unsafe_stack_ptr() { 309 return __safestack_unsafe_stack_ptr; 310} 311