1e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev//===-- asan_posix.cc -----------------------------------------------------===// 2a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// 3a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// The LLVM Compiler Infrastructure 4a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// 5a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// This file is distributed under the University of Illinois Open Source 6a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// License. See LICENSE.TXT for details. 7a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// 8a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany//===----------------------------------------------------------------------===// 9a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// 10a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 11a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// 12a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// Posix-specific details. 13a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany//===----------------------------------------------------------------------===// 1424e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov 1524e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#include "sanitizer_common/sanitizer_platform.h" 162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_POSIX 17a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 18a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include "asan_internal.h" 19a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include "asan_interceptors.h" 20c99f70044d64482adbc1053f04b32bdbf0d4c057Evgeniy Stepanov#include "asan_mapping.h" 217354509ec8a37262c5ea0c54f99afee8a5116ce5Alexey Samsonov#include "asan_report.h" 22a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include "asan_stack.h" 232221f553886c37401b5d84923634ebf04bc482f1Alexey Samsonov#include "sanitizer_common/sanitizer_libc.h" 24259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar#include "sanitizer_common/sanitizer_posix.h" 256895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov#include "sanitizer_common/sanitizer_procmaps.h" 26a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 27cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany#include <pthread.h> 28a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include <signal.h> 29b823e3c5f7891dbbde1eb288237f5f3d5ed64d85Alexey Samsonov#include <stdlib.h> 30a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include <sys/time.h> 31a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include <sys/resource.h> 320ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryany#include <unistd.h> 33a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 34a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryanynamespace __asan { 35a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 36799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainarvoid AsanOnDeadlySignal(int signo, void *siginfo, void *context) { 376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ScopedDeadlySignal signal_scope(GetCurrentThread()); 382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines int code = (int)((siginfo_t*)siginfo)->si_code; 39c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Write the first message using fd=2, just in case. 40c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // It may actually fail to write in case stderr is closed. 41c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar internal_write(2, "ASAN:DEADLYSIGNAL\n", 18); 4286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SignalContext sig = SignalContext::Create(siginfo, context); 43f03d8afc8b8dd072c4e2884a7475ee28ac5f3f41Alexander Potapenko 442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Access at a reasonable offset above SP, or slightly below it (to account 456d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // for x86_64 or PowerPC redzone, ARM push of multiple registers, etc) is 466d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // probably a stack overflow. 47c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef __s390__ 48c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // On s390, the fault address in siginfo points to start of the page, not 49c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // to the precise word that was accessed. Mask off the low bits of sp to 50c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // take it into account. 51c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar bool IsStackAccess = sig.addr >= (sig.sp & ~0xFFF) && 52c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar sig.addr < sig.sp + 0xFFFF; 53c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#else 5486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines bool IsStackAccess = sig.addr + 512 > sig.sp && sig.addr < sig.sp + 0xFFFF; 55c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif 566d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 576d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if __powerpc__ 586d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // Large stack frames can be allocated with e.g. 596d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // lis r0,-10000 606d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // stdux r1,r1,r0 # store sp to [sp-10000] and update sp by -10000 616d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // If the store faults then sp will not have been updated, so test above 626d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // will not work, becase the fault address will be more than just "slightly" 636d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // below sp. 6486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!IsStackAccess && IsAccessibleMemoryRange(sig.pc, 4)) { 6586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines u32 inst = *(unsigned *)sig.pc; 666d1862363c88c183b0ed7740fca876342cf0474bStephen Hines u32 ra = (inst >> 16) & 0x1F; 676d1862363c88c183b0ed7740fca876342cf0474bStephen Hines u32 opcd = inst >> 26; 686d1862363c88c183b0ed7740fca876342cf0474bStephen Hines u32 xo = (inst >> 1) & 0x3FF; 696d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // Check for store-with-update to sp. The instructions we accept are: 706d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // stbu rs,d(ra) stbux rs,ra,rb 716d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // sthu rs,d(ra) sthux rs,ra,rb 726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // stwu rs,d(ra) stwux rs,ra,rb 736d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // stdu rs,ds(ra) stdux rs,ra,rb 746d1862363c88c183b0ed7740fca876342cf0474bStephen Hines // where ra is r1 (the stack pointer). 756d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (ra == 1 && 766d1862363c88c183b0ed7740fca876342cf0474bStephen Hines (opcd == 39 || opcd == 45 || opcd == 37 || opcd == 62 || 776d1862363c88c183b0ed7740fca876342cf0474bStephen Hines (opcd == 31 && (xo == 247 || xo == 439 || xo == 183 || xo == 181)))) 786d1862363c88c183b0ed7740fca876342cf0474bStephen Hines IsStackAccess = true; 796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines } 806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#endif // __powerpc__ 816d1862363c88c183b0ed7740fca876342cf0474bStephen Hines 822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // We also check si_code to filter out SEGV caused by something else other 832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // then hitting the guard page or unmapped memory, like, for example, 842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // unaligned memory access. 856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines if (IsStackAccess && (code == si_SEGV_MAPERR || code == si_SEGV_ACCERR)) 8686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ReportStackOverflow(sig); 87799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar else if (signo == SIGFPE) 88799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ReportDeadlySignal("FPE", sig); 89799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar else if (signo == SIGILL) 90799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ReportDeadlySignal("ILL", sig); 912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines else 92799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar ReportDeadlySignal("SEGV", sig); 93a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany} 94a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 95cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany// ---------------------- TSD ---------------- {{{1 96cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany 97cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryanystatic pthread_key_t tsd_key; 98cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryanystatic bool tsd_key_inited = false; 99f58f998066db0231e521169d2f50af439ceecb49Kostya Serebryanyvoid AsanTSDInit(void (*destructor)(void *tsd)) { 100cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany CHECK(!tsd_key_inited); 101cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany tsd_key_inited = true; 102a27bdf70ca24202dce21cf7c1a387aeaa400d889Kostya Serebryany CHECK_EQ(0, pthread_key_create(&tsd_key, destructor)); 103cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany} 104cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany 105cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryanyvoid *AsanTSDGet() { 106cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany CHECK(tsd_key_inited); 107cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany return pthread_getspecific(tsd_key); 108cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany} 109cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany 110cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryanyvoid AsanTSDSet(void *tsd) { 111cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany CHECK(tsd_key_inited); 112cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany pthread_setspecific(tsd_key, tsd); 113cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany} 114cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany 115e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveevvoid PlatformTSDDtor(void *tsd) { 116e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev AsanThreadContext *context = (AsanThreadContext*)tsd; 117e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev if (context->destructor_iterations > 1) { 118e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev context->destructor_iterations--; 119e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev CHECK_EQ(0, pthread_setspecific(tsd_key, tsd)); 120e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev return; 121e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev } 122e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev AsanThread::TSDDtor(tsd); 123e86e35fbe861e73c5991200510a028877427b3e7Sergey Matveev} 124a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany} // namespace __asan 125a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif // SANITIZER_POSIX 127