asan_linux.cc revision 799172d60d32feb1acba1a6867f3a9c39a999e5c
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() {} 727c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar 731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *AsanDoesNotSupportStaticLinkage() { 741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // This will fail to link with -static. 75efb3fa36cf421c346e8e54054cdae4fd798edab7Kostya Serebryany return &_DYNAMIC; // defined in link.h 761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 7883cb7877f608eb9b3d65981095216842f686c527Evgeniy Stepanov#if SANITIZER_ANDROID 792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FIXME: should we do anything for Android? 802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckDynamicRTPrereqs() {} 812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckIncompatibleRT() {} 822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else 832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size, 842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void *data) { 852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Continue until the first dynamic library is found 862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (!info->dlpi_name || info->dlpi_name[0] == 0) 872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 0; 882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 896a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines // Ignore vDSO 906a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines if (internal_strncmp(info->dlpi_name, "linux-", sizeof("linux-") - 1) == 0) 916a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines return 0; 926a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines 932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines *(const char **)data = info->dlpi_name; 942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 1; 952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic bool IsDynamicRTName(const char *libname) { 982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return internal_strstr(libname, "libclang_rt.asan") || 992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines internal_strstr(libname, "libasan.so"); 1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic void ReportIncompatibleRT() { 1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report("Your application is linked against incompatible ASan runtimes.\n"); 1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Die(); 1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckDynamicRTPrereqs() { 108cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar if (!ASAN_DYNAMIC) 109cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar return; 110cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar 1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Ensure that dynamic RT is the first DSO in the list 112799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar const char *first_dso_name = nullptr; 1132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines dl_iterate_phdr(FindFirstDSOCallback, &first_dso_name); 1142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (first_dso_name && !IsDynamicRTName(first_dso_name)) { 1152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report("ASan runtime does not come first in initial library list; " 1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "you should either link runtime to your application or " 1172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "manually preload it with LD_PRELOAD.\n"); 1182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Die(); 1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckIncompatibleRT() { 1232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (ASAN_DYNAMIC) { 1242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (__asan_rt_version == ASAN_RT_VERSION_UNDEFINED) { 1252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines __asan_rt_version = ASAN_RT_VERSION_DYNAMIC; 1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } else if (__asan_rt_version != ASAN_RT_VERSION_DYNAMIC) { 1272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ReportIncompatibleRT(); 1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } else { 1302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (__asan_rt_version == ASAN_RT_VERSION_UNDEFINED) { 1312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Ensure that dynamic runtime is not present. We should detect it 1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // as early as possible, otherwise ASan interceptors could bind to 1332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // the functions in dynamic ASan runtime instead of the functions in 1342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // system libraries, causing crashes later in ASan initialization. 1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines MemoryMappingLayout proc_maps(/*cache_enabled*/true); 1362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines char filename[128]; 137799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar while (proc_maps.Next(nullptr, nullptr, nullptr, filename, 138799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar sizeof(filename), nullptr)) { 1392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (IsDynamicRTName(filename)) { 1402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Report("Your application is linked against " 1412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "incompatible ASan runtimes.\n"); 1422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines Die(); 1432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines __asan_rt_version = ASAN_RT_VERSION_STATIC; 1462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } else if (__asan_rt_version != ASAN_RT_VERSION_STATIC) { 1472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ReportIncompatibleRT(); 1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 151799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif // SANITIZER_ANDROID 15275b19ebf25af204cf209d108997272822241d6daAlexander Potapenko 15383cb7877f608eb9b3d65981095216842f686c527Evgeniy Stepanov#if !SANITIZER_ANDROID 15457db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonovvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) { 155f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov ucontext_t *ucp = (ucontext_t*)context; 15657db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov *stack = (uptr)ucp->uc_stack.ss_sp; 15757db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov *ssize = ucp->uc_stack.ss_size; 158f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov} 159f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov#else 16057db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonovvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) { 161ca2849c2819b5c7a8771a1e8bc449cf8f5ef6527Alexey Samsonov UNIMPLEMENTED(); 162f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov} 163f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov#endif 164f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov 1656a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesvoid *AsanDlSymNext(const char *sym) { 1666a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines return dlsym(RTLD_NEXT, sym); 1676a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines} 1686a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines 169799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar} // namespace __asan 170d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany 171799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif // SANITIZER_FREEBSD || SANITIZER_LINUX 172