Path: blob/main/contrib/llvm-project/compiler-rt/lib/tysan/tysan_interceptors.cpp
213766 views
//===-- tysan_interceptors.cpp --------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is a part of TypeSanitizer.9//10// Interceptors for standard library functions.11//===----------------------------------------------------------------------===//1213#include "interception/interception.h"14#include "sanitizer_common/sanitizer_allocator_dlsym.h"15#include "sanitizer_common/sanitizer_common.h"16#include "tysan/tysan.h"1718#if SANITIZER_LINUX && !SANITIZER_ANDROID19#define TYSAN_INTERCEPT___STRDUP 120#else21#define TYSAN_INTERCEPT___STRDUP 022#endif2324#if SANITIZER_LINUX25extern "C" int mallopt(int param, int value);26#endif2728using namespace __sanitizer;29using namespace __tysan;3031namespace {32struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {33static bool UseImpl() { return !tysan_inited; }34};35} // namespace3637INTERCEPTOR(void *, memset, void *dst, int v, uptr size) {38if (!tysan_inited && REAL(memset) == nullptr)39return internal_memset(dst, v, size);4041void *res = REAL(memset)(dst, v, size);42tysan_set_type_unknown(dst, size);43return res;44}4546INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) {47if (!tysan_inited && REAL(memmove) == nullptr)48return internal_memmove(dst, src, size);4950void *res = REAL(memmove)(dst, src, size);51tysan_copy_types(dst, src, size);52return res;53}5455INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) {56if (!tysan_inited && REAL(memcpy) == nullptr) {57// memmove is used here because on some platforms this will also58// intercept the memmove implementation.59return internal_memmove(dst, src, size);60}6162void *res = REAL(memcpy)(dst, src, size);63tysan_copy_types(dst, src, size);64return res;65}6667INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,68int fd, OFF_T offset) {69void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);70if (res != (void *)-1)71tysan_set_type_unknown(res, RoundUpTo(length, GetPageSize()));72return res;73}7475#if !SANITIZER_APPLE76INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,77int fd, OFF64_T offset) {78void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);79if (res != (void *)-1)80tysan_set_type_unknown(res, RoundUpTo(length, GetPageSize()));81return res;82}83#endif8485INTERCEPTOR(char *, strdup, const char *s) {86char *res = REAL(strdup)(s);87if (res)88tysan_copy_types(res, const_cast<char *>(s), internal_strlen(s));89return res;90}9192#if TYSAN_INTERCEPT___STRDUP93INTERCEPTOR(char *, __strdup, const char *s) {94char *res = REAL(__strdup)(s);95if (res)96tysan_copy_types(res, const_cast<char *>(s), internal_strlen(s));97return res;98}99#endif // TYSAN_INTERCEPT___STRDUP100101INTERCEPTOR(void *, malloc, uptr size) {102if (DlsymAlloc::Use())103return DlsymAlloc::Allocate(size);104void *res = REAL(malloc)(size);105if (res)106tysan_set_type_unknown(res, size);107return res;108}109110#if SANITIZER_APPLE111INTERCEPTOR(uptr, malloc_size, void *ptr) {112if (DlsymAlloc::PointerIsMine(ptr))113return DlsymAlloc::GetSize(ptr);114return REAL(malloc_size)(ptr);115}116#endif117118INTERCEPTOR(void *, realloc, void *ptr, uptr size) {119if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))120return DlsymAlloc::Realloc(ptr, size);121void *res = REAL(realloc)(ptr, size);122// We might want to copy the types from the original allocation (although123// that would require that we knew its size).124if (res)125tysan_set_type_unknown(res, size);126return res;127}128129INTERCEPTOR(void *, calloc, uptr nmemb, uptr size) {130if (DlsymAlloc::Use())131return DlsymAlloc::Callocate(nmemb, size);132void *res = REAL(calloc)(nmemb, size);133if (res)134tysan_set_type_unknown(res, nmemb * size);135return res;136}137138INTERCEPTOR(void, free, void *ptr) {139if (DlsymAlloc::PointerIsMine(ptr))140return DlsymAlloc::Free(ptr);141REAL(free)(ptr);142}143144INTERCEPTOR(void *, valloc, uptr size) {145void *res = REAL(valloc)(size);146if (res)147tysan_set_type_unknown(res, size);148return res;149}150151#if SANITIZER_INTERCEPT_MEMALIGN152INTERCEPTOR(void *, memalign, uptr alignment, uptr size) {153void *res = REAL(memalign)(alignment, size);154if (res)155tysan_set_type_unknown(res, size);156return res;157}158#define TYSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)159#else160#define TYSAN_MAYBE_INTERCEPT_MEMALIGN161#endif // SANITIZER_INTERCEPT_MEMALIGN162163#if SANITIZER_INTERCEPT___LIBC_MEMALIGN164INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) {165void *res = REAL(__libc_memalign)(alignment, size);166if (res)167tysan_set_type_unknown(res, size);168return res;169}170#define TYSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN \171INTERCEPT_FUNCTION(__libc_memalign)172#else173#define TYSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN174#endif // SANITIZER_INTERCEPT___LIBC_MEMALIGN175176#if SANITIZER_INTERCEPT_PVALLOC177INTERCEPTOR(void *, pvalloc, uptr size) {178void *res = REAL(pvalloc)(size);179if (res)180tysan_set_type_unknown(res, size);181return res;182}183#define TYSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)184#else185#define TYSAN_MAYBE_INTERCEPT_PVALLOC186#endif // SANITIZER_INTERCEPT_PVALLOC187188#if SANITIZER_INTERCEPT_ALIGNED_ALLOC189INTERCEPTOR(void *, aligned_alloc, uptr alignment, uptr size) {190void *res = REAL(aligned_alloc)(alignment, size);191if (res)192tysan_set_type_unknown(res, size);193return res;194}195#define TYSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc)196#else197#define TYSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC198#endif199200INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {201int res = REAL(posix_memalign)(memptr, alignment, size);202if (res == 0 && *memptr)203tysan_set_type_unknown(*memptr, size);204return res;205}206207namespace __tysan {208void InitializeInterceptors() {209static int inited = 0;210CHECK_EQ(inited, 0);211212// Instruct libc malloc to consume less memory.213#if SANITIZER_LINUX214mallopt(1, 0); // M_MXFAST215mallopt(-3, 32 * 1024); // M_MMAP_THRESHOLD216#endif217218INTERCEPT_FUNCTION(mmap);219220INTERCEPT_FUNCTION(mmap64);221222INTERCEPT_FUNCTION(strdup);223#if TYSAN_INTERCEPT___STRDUP224INTERCEPT_FUNCTION(__strdup);225#endif226227INTERCEPT_FUNCTION(malloc);228INTERCEPT_FUNCTION(calloc);229INTERCEPT_FUNCTION(free);230INTERCEPT_FUNCTION(realloc);231INTERCEPT_FUNCTION(valloc);232TYSAN_MAYBE_INTERCEPT_MEMALIGN;233TYSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;234TYSAN_MAYBE_INTERCEPT_PVALLOC;235TYSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC236INTERCEPT_FUNCTION(posix_memalign);237238INTERCEPT_FUNCTION(memset);239INTERCEPT_FUNCTION(memmove);240INTERCEPT_FUNCTION(memcpy);241242inited = 1;243}244} // namespace __tysan245246247