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