brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · a9c55a3 Raw
246 lines · cpp
1//===-- tysan_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 TypeSanitizer.10//11// Interceptors for standard library functions.12//===----------------------------------------------------------------------===//13 14#include "interception/interception.h"15#include "sanitizer_common/sanitizer_allocator_dlsym.h"16#include "sanitizer_common/sanitizer_common.h"17#include "tysan/tysan.h"18 19#if SANITIZER_LINUX && !SANITIZER_ANDROID20#define TYSAN_INTERCEPT___STRDUP 121#else22#define TYSAN_INTERCEPT___STRDUP 023#endif24 25#if SANITIZER_LINUX26extern "C" int mallopt(int param, int value);27#endif28 29using namespace __sanitizer;30using namespace __tysan;31 32namespace {33struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {34  static bool UseImpl() { return !tysan_inited; }35};36} // namespace37 38INTERCEPTOR(void *, memset, void *dst, int v, uptr size) {39  if (!tysan_inited && REAL(memset) == nullptr)40    return internal_memset(dst, v, size);41 42  void *res = REAL(memset)(dst, v, size);43  tysan_set_type_unknown(dst, size);44  return res;45}46 47INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) {48  if (!tysan_inited && REAL(memmove) == nullptr)49    return internal_memmove(dst, src, size);50 51  void *res = REAL(memmove)(dst, src, size);52  tysan_copy_types(dst, src, size);53  return res;54}55 56INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) {57  if (!tysan_inited && REAL(memcpy) == nullptr) {58    // memmove is used here because on some platforms this will also59    // intercept the memmove implementation.60    return internal_memmove(dst, src, size);61  }62 63  void *res = REAL(memcpy)(dst, src, size);64  tysan_copy_types(dst, src, size);65  return res;66}67 68INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,69            int fd, OFF_T offset) {70  void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);71  if (res != (void *)-1)72    tysan_set_type_unknown(res, RoundUpTo(length, GetPageSize()));73  return res;74}75 76#if !SANITIZER_APPLE77INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,78            int fd, OFF64_T offset) {79  void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);80  if (res != (void *)-1)81    tysan_set_type_unknown(res, RoundUpTo(length, GetPageSize()));82  return res;83}84#endif85 86INTERCEPTOR(char *, strdup, const char *s) {87  char *res = REAL(strdup)(s);88  if (res)89    tysan_copy_types(res, const_cast<char *>(s), internal_strlen(s));90  return res;91}92 93#if TYSAN_INTERCEPT___STRDUP94INTERCEPTOR(char *, __strdup, const char *s) {95  char *res = REAL(__strdup)(s);96  if (res)97    tysan_copy_types(res, const_cast<char *>(s), internal_strlen(s));98  return res;99}100#endif // TYSAN_INTERCEPT___STRDUP101 102INTERCEPTOR(void *, malloc, uptr size) {103  if (DlsymAlloc::Use())104    return DlsymAlloc::Allocate(size);105  void *res = REAL(malloc)(size);106  if (res)107    tysan_set_type_unknown(res, size);108  return res;109}110 111#if SANITIZER_APPLE112INTERCEPTOR(uptr, malloc_size, void *ptr) {113  if (DlsymAlloc::PointerIsMine(ptr))114    return DlsymAlloc::GetSize(ptr);115  return REAL(malloc_size)(ptr);116}117#endif118 119INTERCEPTOR(void *, realloc, void *ptr, uptr size) {120  if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))121    return DlsymAlloc::Realloc(ptr, size);122  void *res = REAL(realloc)(ptr, size);123  // We might want to copy the types from the original allocation (although124  // that would require that we knew its size).125  if (res)126    tysan_set_type_unknown(res, size);127  return res;128}129 130INTERCEPTOR(void *, calloc, uptr nmemb, uptr size) {131  if (DlsymAlloc::Use())132    return DlsymAlloc::Callocate(nmemb, size);133  void *res = REAL(calloc)(nmemb, size);134  if (res)135    tysan_set_type_unknown(res, nmemb * size);136  return res;137}138 139INTERCEPTOR(void, free, void *ptr) {140  if (DlsymAlloc::PointerIsMine(ptr))141    return DlsymAlloc::Free(ptr);142  REAL(free)(ptr);143}144 145INTERCEPTOR(void *, valloc, uptr size) {146  void *res = REAL(valloc)(size);147  if (res)148    tysan_set_type_unknown(res, size);149  return res;150}151 152#if SANITIZER_INTERCEPT_MEMALIGN153INTERCEPTOR(void *, memalign, uptr alignment, uptr size) {154  void *res = REAL(memalign)(alignment, size);155  if (res)156    tysan_set_type_unknown(res, size);157  return res;158}159#define TYSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)160#else161#define TYSAN_MAYBE_INTERCEPT_MEMALIGN162#endif // SANITIZER_INTERCEPT_MEMALIGN163 164#if SANITIZER_INTERCEPT___LIBC_MEMALIGN165INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) {166  void *res = REAL(__libc_memalign)(alignment, size);167  if (res)168    tysan_set_type_unknown(res, size);169  return res;170}171#define TYSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN                                  \172  INTERCEPT_FUNCTION(__libc_memalign)173#else174#define TYSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN175#endif // SANITIZER_INTERCEPT___LIBC_MEMALIGN176 177#if SANITIZER_INTERCEPT_PVALLOC178INTERCEPTOR(void *, pvalloc, uptr size) {179  void *res = REAL(pvalloc)(size);180  if (res)181    tysan_set_type_unknown(res, size);182  return res;183}184#define TYSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)185#else186#define TYSAN_MAYBE_INTERCEPT_PVALLOC187#endif // SANITIZER_INTERCEPT_PVALLOC188 189#if SANITIZER_INTERCEPT_ALIGNED_ALLOC190INTERCEPTOR(void *, aligned_alloc, uptr alignment, uptr size) {191  void *res = REAL(aligned_alloc)(alignment, size);192  if (res)193    tysan_set_type_unknown(res, size);194  return res;195}196#define TYSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc)197#else198#define TYSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC199#endif200 201INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {202  int res = REAL(posix_memalign)(memptr, alignment, size);203  if (res == 0 && *memptr)204    tysan_set_type_unknown(*memptr, size);205  return res;206}207 208namespace __tysan {209void InitializeInterceptors() {210  static int inited = 0;211  CHECK_EQ(inited, 0);212 213  // Instruct libc malloc to consume less memory.214#if SANITIZER_LINUX215  mallopt(1, 0);          // M_MXFAST216  mallopt(-3, 32 * 1024); // M_MMAP_THRESHOLD217#endif218 219  INTERCEPT_FUNCTION(mmap);220 221  INTERCEPT_FUNCTION(mmap64);222 223  INTERCEPT_FUNCTION(strdup);224#if TYSAN_INTERCEPT___STRDUP225  INTERCEPT_FUNCTION(__strdup);226#endif227 228  INTERCEPT_FUNCTION(malloc);229  INTERCEPT_FUNCTION(calloc);230  INTERCEPT_FUNCTION(free);231  INTERCEPT_FUNCTION(realloc);232  INTERCEPT_FUNCTION(valloc);233  TYSAN_MAYBE_INTERCEPT_MEMALIGN;234  TYSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;235  TYSAN_MAYBE_INTERCEPT_PVALLOC;236  TYSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC237  INTERCEPT_FUNCTION(posix_memalign);238 239  INTERCEPT_FUNCTION(memset);240  INTERCEPT_FUNCTION(memmove);241  INTERCEPT_FUNCTION(memcpy);242 243  inited = 1;244}245} // namespace __tysan246