Path: blob/main/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_interceptors.cpp
35233 views
//===-- dfsan_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 DataFlowSanitizer.9//10// Interceptors for standard library functions.11//===----------------------------------------------------------------------===//1213#include <sys/syscall.h>14#include <unistd.h>1516#include "dfsan/dfsan.h"17#include "dfsan/dfsan_thread.h"18#include "interception/interception.h"19#include "sanitizer_common/sanitizer_allocator_dlsym.h"20#include "sanitizer_common/sanitizer_allocator_interface.h"21#include "sanitizer_common/sanitizer_common.h"22#include "sanitizer_common/sanitizer_errno.h"23#include "sanitizer_common/sanitizer_platform_limits_posix.h"24#include "sanitizer_common/sanitizer_posix.h"25#include "sanitizer_common/sanitizer_tls_get_addr.h"2627using namespace __sanitizer;2829static bool interceptors_initialized;3031struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {32static bool UseImpl() { return !__dfsan::dfsan_inited; }33};3435INTERCEPTOR(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size) {36return __dfsan::dfsan_reallocarray(ptr, nmemb, size);37}3839INTERCEPTOR(void *, __libc_memalign, SIZE_T alignment, SIZE_T size) {40void *ptr = __dfsan::dfsan_memalign(alignment, size);41if (ptr)42DTLS_on_libc_memalign(ptr, size);43return ptr;44}4546INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) {47return __dfsan::dfsan_aligned_alloc(alignment, size);48}4950INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {51if (DlsymAlloc::Use())52return DlsymAlloc::Callocate(nmemb, size);53return __dfsan::dfsan_calloc(nmemb, size);54}5556INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {57if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))58return DlsymAlloc::Realloc(ptr, size);59return __dfsan::dfsan_realloc(ptr, size);60}6162INTERCEPTOR(void *, malloc, SIZE_T size) {63if (DlsymAlloc::Use())64return DlsymAlloc::Allocate(size);65return __dfsan::dfsan_malloc(size);66}6768INTERCEPTOR(void, free, void *ptr) {69if (!ptr)70return;71if (DlsymAlloc::PointerIsMine(ptr))72return DlsymAlloc::Free(ptr);73return __dfsan::dfsan_deallocate(ptr);74}7576INTERCEPTOR(void, cfree, void *ptr) {77if (!ptr)78return;79if (DlsymAlloc::PointerIsMine(ptr))80return DlsymAlloc::Free(ptr);81return __dfsan::dfsan_deallocate(ptr);82}8384INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {85CHECK_NE(memptr, 0);86int res = __dfsan::dfsan_posix_memalign(memptr, alignment, size);87if (!res)88dfsan_set_label(0, memptr, sizeof(*memptr));89return res;90}9192INTERCEPTOR(void *, memalign, SIZE_T alignment, SIZE_T size) {93return __dfsan::dfsan_memalign(alignment, size);94}9596INTERCEPTOR(void *, valloc, SIZE_T size) { return __dfsan::dfsan_valloc(size); }9798INTERCEPTOR(void *, pvalloc, SIZE_T size) {99return __dfsan::dfsan_pvalloc(size);100}101102INTERCEPTOR(void, mallinfo, __sanitizer_struct_mallinfo *sret) {103internal_memset(sret, 0, sizeof(*sret));104dfsan_set_label(0, sret, sizeof(*sret));105}106107INTERCEPTOR(int, mallopt, int cmd, int value) { return 0; }108109INTERCEPTOR(void, malloc_stats, void) {110// FIXME: implement, but don't call REAL(malloc_stats)!111}112113INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {114return __sanitizer_get_allocated_size(ptr);115}116117#define ENSURE_DFSAN_INITED() \118do { \119CHECK(!__dfsan::dfsan_init_is_running); \120if (!__dfsan::dfsan_inited) { \121__dfsan::dfsan_init(); \122} \123} while (0)124125#define COMMON_INTERCEPTOR_ENTER(func, ...) \126if (__dfsan::dfsan_init_is_running) \127return REAL(func)(__VA_ARGS__); \128ENSURE_DFSAN_INITED(); \129dfsan_set_label(0, __errno_location(), sizeof(int));130131INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,132int fd, OFF_T offset) {133if (common_flags()->detect_write_exec)134ReportMmapWriteExec(prot, flags);135if (!__dfsan::dfsan_inited)136return (void *)internal_mmap(addr, length, prot, flags, fd, offset);137COMMON_INTERCEPTOR_ENTER(mmap, addr, length, prot, flags, fd, offset);138void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);139if (res != (void *)-1) {140dfsan_set_label(0, res, RoundUpTo(length, GetPageSizeCached()));141}142return res;143}144145INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,146int fd, OFF64_T offset) {147if (common_flags()->detect_write_exec)148ReportMmapWriteExec(prot, flags);149if (!__dfsan::dfsan_inited)150return (void *)internal_mmap(addr, length, prot, flags, fd, offset);151COMMON_INTERCEPTOR_ENTER(mmap64, addr, length, prot, flags, fd, offset);152void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);153if (res != (void *)-1) {154dfsan_set_label(0, res, RoundUpTo(length, GetPageSizeCached()));155}156return res;157}158159INTERCEPTOR(int, munmap, void *addr, SIZE_T length) {160if (!__dfsan::dfsan_inited)161return internal_munmap(addr, length);162COMMON_INTERCEPTOR_ENTER(munmap, addr, length);163int res = REAL(munmap)(addr, length);164if (res != -1)165dfsan_set_label(0, addr, RoundUpTo(length, GetPageSizeCached()));166return res;167}168169#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \170if (__dfsan::DFsanThread *t = __dfsan::GetCurrentThread()) { \171*begin = t->tls_begin(); \172*end = t->tls_end(); \173} else { \174*begin = *end = 0; \175}176#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size) \177dfsan_set_label(0, ptr, size)178179INTERCEPTOR(void *, __tls_get_addr, void *arg) {180COMMON_INTERCEPTOR_ENTER(__tls_get_addr, arg);181void *res = REAL(__tls_get_addr)(arg);182uptr tls_begin, tls_end;183COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);184DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);185if (dtv) {186// New DTLS block has been allocated.187COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);188}189return res;190}191192namespace __dfsan {193void initialize_interceptors() {194CHECK(!interceptors_initialized);195196INTERCEPT_FUNCTION(aligned_alloc);197INTERCEPT_FUNCTION(calloc);198INTERCEPT_FUNCTION(cfree);199INTERCEPT_FUNCTION(free);200INTERCEPT_FUNCTION(mallinfo);201INTERCEPT_FUNCTION(malloc);202INTERCEPT_FUNCTION(malloc_stats);203INTERCEPT_FUNCTION(malloc_usable_size);204INTERCEPT_FUNCTION(mallopt);205INTERCEPT_FUNCTION(memalign);206INTERCEPT_FUNCTION(mmap);207INTERCEPT_FUNCTION(mmap64);208INTERCEPT_FUNCTION(munmap);209INTERCEPT_FUNCTION(posix_memalign);210INTERCEPT_FUNCTION(pvalloc);211INTERCEPT_FUNCTION(realloc);212INTERCEPT_FUNCTION(reallocarray);213INTERCEPT_FUNCTION(valloc);214INTERCEPT_FUNCTION(__tls_get_addr);215INTERCEPT_FUNCTION(__libc_memalign);216217interceptors_initialized = true;218}219} // namespace __dfsan220221222