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