11e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===-- asan_linux.cc -----------------------------------------------------===// 21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The LLVM Compiler Infrastructure 41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source 61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details. 71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Linux-specific details. 131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 1424e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov 1524e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#include "sanitizer_common/sanitizer_platform.h" 162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_FREEBSD || SANITIZER_LINUX 171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 18df499b44de81fc757a789878f07fcaf19ebb0016Kostya Serebryany#include "asan_interceptors.h" 191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h" 20c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany#include "asan_thread.h" 212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common/sanitizer_flags.h" 226a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#include "sanitizer_common/sanitizer_freebsd.h" 23ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#include "sanitizer_common/sanitizer_libc.h" 246895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov#include "sanitizer_common/sanitizer_procmaps.h" 251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 26c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany#include <sys/time.h> 27c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany#include <sys/resource.h> 281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <sys/mman.h> 291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <sys/syscall.h> 30de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany#include <sys/types.h> 316a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#include <dlfcn.h> 32de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany#include <fcntl.h> 33c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany#include <pthread.h> 34df499b44de81fc757a789878f07fcaf19ebb0016Kostya Serebryany#include <stdio.h> 351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <unistd.h> 369cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#include <unwind.h> 371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_FREEBSD 392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <sys/link_elf.h> 409107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#endif 419107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany 422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_ANDROID || SANITIZER_FREEBSD 432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <ucontext.h> 44aa33a50c9d0f3e3f22c8b21fa7309ec91f9d939aEvgeniy Stepanovextern "C" void* _DYNAMIC; 452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else 462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <sys/ucontext.h> 472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <link.h> 482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 506a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// x86-64 FreeBSD 9.2 and older define 'ucontext_t' incorrectly in 516a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// 32-bit mode. 526a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) && \ 536a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines __FreeBSD_version <= 902001 // v9.2 546a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#define ucontext_t xucontext_t 552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinestypedef enum { 582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ASAN_RT_VERSION_UNDEFINED = 0, 592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ASAN_RT_VERSION_DYNAMIC, 602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ASAN_RT_VERSION_STATIC, 612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} asan_rt_version_t; 622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FIXME: perhaps also store abi version here? 642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesextern "C" { 652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesSANITIZER_INTERFACE_ATTRIBUTE 662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesasan_rt_version_t __asan_rt_version; 672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 68aa33a50c9d0f3e3f22c8b21fa7309ec91f9d939aEvgeniy Stepanov 691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 717c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainarvoid InitializePlatformInterceptors() {} 72c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarvoid InitializePlatformExceptionHandlers() {} 737c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar 741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *AsanDoesNotSupportStaticLinkage() { 751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // This will fail to link with -static. 76efb3fa36cf421c346e8e54054cdae4fd798edab7Kostya Serebryany return &_DYNAMIC; // defined in link.h 771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 79c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarvoid AsanApplyToGlobals(globals_op_fptr op, const void *needle) { 80c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar UNIMPLEMENTED(); 81c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 82c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 8383cb7877f608eb9b3d65981095216842f686c527Evgeniy Stepanov#if SANITIZER_ANDROID 842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FIXME: should we do anything for Android? 852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckDynamicRTPrereqs() {} 862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckIncompatibleRT() {} 872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else 882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size, 892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void *data) { 902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Continue until the first dynamic library is found 912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (!info->dlpi_name || info->dlpi_name[0] == 0) 922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 0; 932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 946a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines // Ignore vDSO 956a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines if (internal_strncmp(info->dlpi_name, "linux-", sizeof("linux-") - 1) == 0) 966a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines return 0; 976a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines 982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines *(const char **)data = info->dlpi_name; 992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 1; 1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic bool IsDynamicRTName(const char *libname) { 1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return internal_strstr(libname, "libclang_rt.asan") || 1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines internal_strstr(libname, "libasan.so"); 1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void ReportIncompatibleRT() { 1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report("Your application is linked against incompatible ASan runtimes.\n"); 1092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Die(); 1102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckDynamicRTPrereqs() { 113cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar if (!ASAN_DYNAMIC) 114cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar return; 115cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar 1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Ensure that dynamic RT is the first DSO in the list 117799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar const char *first_dso_name = nullptr; 1182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines dl_iterate_phdr(FindFirstDSOCallback, &first_dso_name); 1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (first_dso_name && !IsDynamicRTName(first_dso_name)) { 1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report("ASan runtime does not come first in initial library list; " 1212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "you should either link runtime to your application or " 1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "manually preload it with LD_PRELOAD.\n"); 1232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Die(); 1242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckIncompatibleRT() { 1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (ASAN_DYNAMIC) { 1292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (__asan_rt_version == ASAN_RT_VERSION_UNDEFINED) { 1302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines __asan_rt_version = ASAN_RT_VERSION_DYNAMIC; 1312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } else if (__asan_rt_version != ASAN_RT_VERSION_DYNAMIC) { 1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ReportIncompatibleRT(); 1332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } else { 1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (__asan_rt_version == ASAN_RT_VERSION_UNDEFINED) { 1362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Ensure that dynamic runtime is not present. We should detect it 1372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // as early as possible, otherwise ASan interceptors could bind to 1382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // the functions in dynamic ASan runtime instead of the functions in 1392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // system libraries, causing crashes later in ASan initialization. 1402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines MemoryMappingLayout proc_maps(/*cache_enabled*/true); 1412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines char filename[128]; 142799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar while (proc_maps.Next(nullptr, nullptr, nullptr, filename, 143799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar sizeof(filename), nullptr)) { 1442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (IsDynamicRTName(filename)) { 1452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report("Your application is linked against " 1462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "incompatible ASan runtimes.\n"); 1472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Die(); 1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines __asan_rt_version = ASAN_RT_VERSION_STATIC; 1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } else if (__asan_rt_version != ASAN_RT_VERSION_STATIC) { 1522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ReportIncompatibleRT(); 1532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 156799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif // SANITIZER_ANDROID 15775b19ebf25af204cf209d108997272822241d6daAlexander Potapenko 15883cb7877f608eb9b3d65981095216842f686c527Evgeniy Stepanov#if !SANITIZER_ANDROID 15957db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonovvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) { 160f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov ucontext_t *ucp = (ucontext_t*)context; 16157db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov *stack = (uptr)ucp->uc_stack.ss_sp; 16257db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov *ssize = ucp->uc_stack.ss_size; 163f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov} 164f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov#else 16557db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonovvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) { 166ca2849c2819b5c7a8771a1e8bc449cf8f5ef6527Alexey Samsonov UNIMPLEMENTED(); 167f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov} 168f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov#endif 169f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov 1706a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesvoid *AsanDlSymNext(const char *sym) { 1716a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines return dlsym(RTLD_NEXT, sym); 1726a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines} 1736a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines 174799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar} // namespace __asan 175d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany 176799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif // SANITIZER_FREEBSD || SANITIZER_LINUX 177