brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · 198e6ee Raw
215 lines · cpp
1//===-- dfsan_interceptors.cpp --------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of DataFlowSanitizer.10//11// Interceptors for standard library functions.12//===----------------------------------------------------------------------===//13 14#include <sys/syscall.h>15#include <unistd.h>16 17#include "dfsan/dfsan.h"18#include "dfsan/dfsan_thread.h"19#include "interception/interception.h"20#include "sanitizer_common/sanitizer_allocator_dlsym.h"21#include "sanitizer_common/sanitizer_allocator_interface.h"22#include "sanitizer_common/sanitizer_common.h"23#include "sanitizer_common/sanitizer_errno.h"24#include "sanitizer_common/sanitizer_platform_limits_posix.h"25#include "sanitizer_common/sanitizer_posix.h"26#include "sanitizer_common/sanitizer_tls_get_addr.h"27 28using namespace __dfsan;29using namespace __sanitizer;30 31static bool interceptors_initialized;32 33struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {34  static bool UseImpl() { return !dfsan_inited; }35};36 37INTERCEPTOR(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size) {38  return dfsan_reallocarray(ptr, nmemb, size);39}40 41INTERCEPTOR(void *, __libc_memalign, SIZE_T alignment, SIZE_T size) {42  return dfsan_memalign(alignment, size);43}44 45INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {46  return dfsan_aligned_alloc(alignment, size);47}48 49INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {50  if (DlsymAlloc::Use())51    return DlsymAlloc::Callocate(nmemb, size);52  return dfsan_calloc(nmemb, size);53}54 55INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {56  if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))57    return DlsymAlloc::Realloc(ptr, size);58  return dfsan_realloc(ptr, size);59}60 61INTERCEPTOR(void *, malloc, SIZE_T size) {62  if (DlsymAlloc::Use())63    return DlsymAlloc::Allocate(size);64  return dfsan_malloc(size);65}66 67INTERCEPTOR(void, free, void *ptr) {68  if (!ptr)69    return;70  if (DlsymAlloc::PointerIsMine(ptr))71    return DlsymAlloc::Free(ptr);72  return dfsan_deallocate(ptr);73}74 75INTERCEPTOR(void, cfree, void *ptr) {76  if (!ptr)77    return;78  if (DlsymAlloc::PointerIsMine(ptr))79    return DlsymAlloc::Free(ptr);80  return dfsan_deallocate(ptr);81}82 83INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {84  CHECK_NE(memptr, 0);85  int res = dfsan_posix_memalign(memptr, alignment, size);86  if (!res)87    dfsan_set_label(0, memptr, sizeof(*memptr));88  return res;89}90 91INTERCEPTOR(void *, memalign, SIZE_T alignment, SIZE_T size) {92  return dfsan_memalign(alignment, size);93}94 95INTERCEPTOR(void *, valloc, SIZE_T size) { return dfsan_valloc(size); }96 97INTERCEPTOR(void *, pvalloc, SIZE_T size) { return dfsan_pvalloc(size); }98 99INTERCEPTOR(void, mallinfo, __sanitizer_struct_mallinfo *sret) {100  internal_memset(sret, 0, sizeof(*sret));101  dfsan_set_label(0, sret, sizeof(*sret));102}103 104INTERCEPTOR(int, mallopt, int cmd, int value) { return 0; }105 106INTERCEPTOR(void, malloc_stats, void) {107  // FIXME: implement, but don't call REAL(malloc_stats)!108}109 110INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {111  return __sanitizer_get_allocated_size(ptr);112}113 114#define ENSURE_DFSAN_INITED()      \115  do {                             \116    CHECK(!dfsan_init_is_running); \117    if (!dfsan_inited) {           \118      dfsan_init();                \119    }                              \120  } while (0)121 122#define COMMON_INTERCEPTOR_ENTER(func, ...) \123  if (dfsan_init_is_running)                \124    return REAL(func)(__VA_ARGS__);         \125  ENSURE_DFSAN_INITED();                    \126  dfsan_set_label(0, __errno_location(), sizeof(int));127 128INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,129            int fd, OFF_T offset) {130  if (common_flags()->detect_write_exec)131    ReportMmapWriteExec(prot, flags);132  if (!dfsan_inited)133    return (void *)internal_mmap(addr, length, prot, flags, fd, offset);134  COMMON_INTERCEPTOR_ENTER(mmap, addr, length, prot, flags, fd, offset);135  void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);136  if (res != (void *)-1) {137    dfsan_set_label(0, res, RoundUpTo(length, GetPageSizeCached()));138  }139  return res;140}141 142INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,143            int fd, OFF64_T offset) {144  if (common_flags()->detect_write_exec)145    ReportMmapWriteExec(prot, flags);146  if (!dfsan_inited)147    return (void *)internal_mmap(addr, length, prot, flags, fd, offset);148  COMMON_INTERCEPTOR_ENTER(mmap64, addr, length, prot, flags, fd, offset);149  void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);150  if (res != (void *)-1) {151    dfsan_set_label(0, res, RoundUpTo(length, GetPageSizeCached()));152  }153  return res;154}155 156INTERCEPTOR(int, munmap, void *addr, SIZE_T length) {157  if (!dfsan_inited)158    return internal_munmap(addr, length);159  COMMON_INTERCEPTOR_ENTER(munmap, addr, length);160  int res = REAL(munmap)(addr, length);161  if (res != -1)162    dfsan_set_label(0, addr, RoundUpTo(length, GetPageSizeCached()));163  return res;164}165 166#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \167  if (DFsanThread *t = GetCurrentThread()) {         \168    *begin = t->tls_begin();                         \169    *end = t->tls_end();                             \170  } else {                                           \171    *begin = *end = 0;                               \172  }173#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size) \174  dfsan_set_label(0, ptr, size)175 176INTERCEPTOR(void *, __tls_get_addr, void *arg) {177  COMMON_INTERCEPTOR_ENTER(__tls_get_addr, arg);178  void *res = REAL(__tls_get_addr)(arg);179  uptr tls_begin, tls_end;180  COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);181  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);182  if (dtv) {183    // New DTLS block has been allocated.184    COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);185  }186  return res;187}188 189void __dfsan::initialize_interceptors() {190  CHECK(!interceptors_initialized);191 192  INTERCEPT_FUNCTION(aligned_alloc);193  INTERCEPT_FUNCTION(calloc);194  INTERCEPT_FUNCTION(cfree);195  INTERCEPT_FUNCTION(free);196  INTERCEPT_FUNCTION(mallinfo);197  INTERCEPT_FUNCTION(malloc);198  INTERCEPT_FUNCTION(malloc_stats);199  INTERCEPT_FUNCTION(malloc_usable_size);200  INTERCEPT_FUNCTION(mallopt);201  INTERCEPT_FUNCTION(memalign);202  INTERCEPT_FUNCTION(mmap);203  INTERCEPT_FUNCTION(mmap64);204  INTERCEPT_FUNCTION(munmap);205  INTERCEPT_FUNCTION(posix_memalign);206  INTERCEPT_FUNCTION(pvalloc);207  INTERCEPT_FUNCTION(realloc);208  INTERCEPT_FUNCTION(reallocarray);209  INTERCEPT_FUNCTION(valloc);210  INTERCEPT_FUNCTION(__tls_get_addr);211  INTERCEPT_FUNCTION(__libc_memalign);212 213  interceptors_initialized = true;214}215