1//===-- sanitizer_posix_libcdep.cc ----------------------------------------===// 2// 3// This file is distributed under the University of Illinois Open Source 4// License. See LICENSE.TXT for details. 5// 6//===----------------------------------------------------------------------===// 7// 8// This file is shared between AddressSanitizer and ThreadSanitizer 9// run-time libraries and implements libc-dependent POSIX-specific functions 10// from sanitizer_libc.h. 11//===----------------------------------------------------------------------===// 12 13#include "sanitizer_platform.h" 14 15#if SANITIZER_POSIX 16#include "sanitizer_common.h" 17#include "sanitizer_flags.h" 18#include "sanitizer_platform_limits_posix.h" 19#include "sanitizer_stacktrace.h" 20 21#include <errno.h> 22#include <pthread.h> 23#include <signal.h> 24#include <stdlib.h> 25#include <sys/mman.h> 26#include <sys/resource.h> 27#include <sys/time.h> 28#include <sys/types.h> 29#include <unistd.h> 30 31namespace __sanitizer { 32 33u32 GetUid() { 34 return getuid(); 35} 36 37uptr GetThreadSelf() { 38 return (uptr)pthread_self(); 39} 40 41void FlushUnneededShadowMemory(uptr addr, uptr size) { 42 madvise((void*)addr, size, MADV_DONTNEED); 43} 44 45static rlim_t getlim(int res) { 46 rlimit rlim; 47 CHECK_EQ(0, getrlimit(res, &rlim)); 48 return rlim.rlim_cur; 49} 50 51static void setlim(int res, rlim_t lim) { 52 // The following magic is to prevent clang from replacing it with memset. 53 volatile struct rlimit rlim; 54 rlim.rlim_cur = lim; 55 rlim.rlim_max = lim; 56 if (setrlimit(res, (struct rlimit*)&rlim)) { 57 Report("ERROR: %s setrlimit() failed %d\n", SanitizerToolName, errno); 58 Die(); 59 } 60} 61 62void DisableCoreDumperIfNecessary() { 63 if (common_flags()->disable_coredump) { 64 setlim(RLIMIT_CORE, 0); 65 } 66} 67 68bool StackSizeIsUnlimited() { 69 rlim_t stack_size = getlim(RLIMIT_STACK); 70 return (stack_size == RLIM_INFINITY); 71} 72 73void SetStackSizeLimitInBytes(uptr limit) { 74 setlim(RLIMIT_STACK, (rlim_t)limit); 75 CHECK(!StackSizeIsUnlimited()); 76} 77 78bool AddressSpaceIsUnlimited() { 79 rlim_t as_size = getlim(RLIMIT_AS); 80 return (as_size == RLIM_INFINITY); 81} 82 83void SetAddressSpaceUnlimited() { 84 setlim(RLIMIT_AS, RLIM_INFINITY); 85 CHECK(AddressSpaceIsUnlimited()); 86} 87 88void SleepForSeconds(int seconds) { 89 sleep(seconds); 90} 91 92void SleepForMillis(int millis) { 93 usleep(millis * 1000); 94} 95 96void Abort() { 97 abort(); 98} 99 100int Atexit(void (*function)(void)) { 101#ifndef SANITIZER_GO 102 return atexit(function); 103#else 104 return 0; 105#endif 106} 107 108int internal_isatty(fd_t fd) { 109 return isatty(fd); 110} 111 112#ifndef SANITIZER_GO 113// TODO(glider): different tools may require different altstack size. 114static const uptr kAltStackSize = SIGSTKSZ * 4; // SIGSTKSZ is not enough. 115 116void SetAlternateSignalStack() { 117 stack_t altstack, oldstack; 118 CHECK_EQ(0, sigaltstack(0, &oldstack)); 119 // If the alternate stack is already in place, do nothing. 120 // Android always sets an alternate stack, but it's too small for us. 121 if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return; 122 // TODO(glider): the mapped stack should have the MAP_STACK flag in the 123 // future. It is not required by man 2 sigaltstack now (they're using 124 // malloc()). 125 void* base = MmapOrDie(kAltStackSize, __func__); 126 altstack.ss_sp = (char*) base; 127 altstack.ss_flags = 0; 128 altstack.ss_size = kAltStackSize; 129 CHECK_EQ(0, sigaltstack(&altstack, 0)); 130} 131 132void UnsetAlternateSignalStack() { 133 stack_t altstack, oldstack; 134 altstack.ss_sp = 0; 135 altstack.ss_flags = SS_DISABLE; 136 altstack.ss_size = kAltStackSize; // Some sane value required on Darwin. 137 CHECK_EQ(0, sigaltstack(&altstack, &oldstack)); 138 UnmapOrDie(oldstack.ss_sp, oldstack.ss_size); 139} 140 141typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); 142static void MaybeInstallSigaction(int signum, 143 SignalHandlerType handler) { 144 if (!IsDeadlySignal(signum)) 145 return; 146 struct sigaction sigact; 147 internal_memset(&sigact, 0, sizeof(sigact)); 148 sigact.sa_sigaction = (sa_sigaction_t)handler; 149 // Do not block the signal from being received in that signal's handler. 150 // Clients are responsible for handling this correctly. 151 sigact.sa_flags = SA_SIGINFO | SA_NODEFER; 152 if (common_flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK; 153 CHECK_EQ(0, internal_sigaction(signum, &sigact, 0)); 154 VReport(1, "Installed the sigaction for signal %d\n", signum); 155} 156 157void InstallDeadlySignalHandlers(SignalHandlerType handler) { 158 // Set the alternate signal stack for the main thread. 159 // This will cause SetAlternateSignalStack to be called twice, but the stack 160 // will be actually set only once. 161 if (common_flags()->use_sigaltstack) SetAlternateSignalStack(); 162 MaybeInstallSigaction(SIGSEGV, handler); 163 MaybeInstallSigaction(SIGBUS, handler); 164} 165#endif // SANITIZER_GO 166 167bool IsAccessibleMemoryRange(uptr beg, uptr size) { 168 uptr page_size = GetPageSizeCached(); 169 // Checking too large memory ranges is slow. 170 CHECK_LT(size, page_size * 10); 171 int sock_pair[2]; 172 if (pipe(sock_pair)) 173 return false; 174 uptr bytes_written = 175 internal_write(sock_pair[1], reinterpret_cast<void *>(beg), size); 176 int write_errno; 177 bool result; 178 if (internal_iserror(bytes_written, &write_errno)) { 179 CHECK_EQ(EFAULT, write_errno); 180 result = false; 181 } else { 182 result = (bytes_written == size); 183 } 184 internal_close(sock_pair[0]); 185 internal_close(sock_pair[1]); 186 return result; 187} 188 189} // namespace __sanitizer 190 191#endif // SANITIZER_POSIX 192