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