168d75effSDimitry Andric //===-- dfsan_interceptors.cpp --------------------------------------------===// 268d75effSDimitry Andric // 368d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 468d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 568d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 668d75effSDimitry Andric // 768d75effSDimitry Andric //===----------------------------------------------------------------------===// 868d75effSDimitry Andric // 968d75effSDimitry Andric // This file is a part of DataFlowSanitizer. 1068d75effSDimitry Andric // 1168d75effSDimitry Andric // Interceptors for standard library functions. 1268d75effSDimitry Andric //===----------------------------------------------------------------------===// 1368d75effSDimitry Andric 14*e8d8bef9SDimitry Andric #include <sys/syscall.h> 15*e8d8bef9SDimitry Andric #include <unistd.h> 16*e8d8bef9SDimitry Andric 1768d75effSDimitry Andric #include "dfsan/dfsan.h" 1868d75effSDimitry Andric #include "interception/interception.h" 1968d75effSDimitry Andric #include "sanitizer_common/sanitizer_common.h" 2068d75effSDimitry Andric 2168d75effSDimitry Andric using namespace __sanitizer; 2268d75effSDimitry Andric 23*e8d8bef9SDimitry Andric namespace { 24*e8d8bef9SDimitry Andric 25*e8d8bef9SDimitry Andric bool interceptors_initialized; 26*e8d8bef9SDimitry Andric 27*e8d8bef9SDimitry Andric } // namespace 28*e8d8bef9SDimitry Andric 2968d75effSDimitry Andric INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags, 3068d75effSDimitry Andric int fd, OFF_T offset) { 31*e8d8bef9SDimitry Andric void *res; 32*e8d8bef9SDimitry Andric 33*e8d8bef9SDimitry Andric // interceptors_initialized is set to true during preinit_array, when we're 34*e8d8bef9SDimitry Andric // single-threaded. So we don't need to worry about accessing it atomically. 35*e8d8bef9SDimitry Andric if (!interceptors_initialized) 36*e8d8bef9SDimitry Andric res = (void *)syscall(__NR_mmap, addr, length, prot, flags, fd, offset); 37*e8d8bef9SDimitry Andric else 38*e8d8bef9SDimitry Andric res = REAL(mmap)(addr, length, prot, flags, fd, offset); 39*e8d8bef9SDimitry Andric 4068d75effSDimitry Andric if (res != (void *)-1) 41*e8d8bef9SDimitry Andric dfsan_set_label(0, res, RoundUpTo(length, GetPageSizeCached())); 4268d75effSDimitry Andric return res; 4368d75effSDimitry Andric } 4468d75effSDimitry Andric 4568d75effSDimitry Andric INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags, 4668d75effSDimitry Andric int fd, OFF64_T offset) { 4768d75effSDimitry Andric void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset); 4868d75effSDimitry Andric if (res != (void *)-1) 49*e8d8bef9SDimitry Andric dfsan_set_label(0, res, RoundUpTo(length, GetPageSizeCached())); 50*e8d8bef9SDimitry Andric return res; 51*e8d8bef9SDimitry Andric } 52*e8d8bef9SDimitry Andric 53*e8d8bef9SDimitry Andric INTERCEPTOR(int, munmap, void *addr, SIZE_T length) { 54*e8d8bef9SDimitry Andric int res = REAL(munmap)(addr, length); 55*e8d8bef9SDimitry Andric if (res != -1) 56*e8d8bef9SDimitry Andric dfsan_set_label(0, addr, RoundUpTo(length, GetPageSizeCached())); 5768d75effSDimitry Andric return res; 5868d75effSDimitry Andric } 5968d75effSDimitry Andric 6068d75effSDimitry Andric namespace __dfsan { 6168d75effSDimitry Andric void InitializeInterceptors() { 62*e8d8bef9SDimitry Andric CHECK(!interceptors_initialized); 6368d75effSDimitry Andric 6468d75effSDimitry Andric INTERCEPT_FUNCTION(mmap); 6568d75effSDimitry Andric INTERCEPT_FUNCTION(mmap64); 66*e8d8bef9SDimitry Andric INTERCEPT_FUNCTION(munmap); 67*e8d8bef9SDimitry Andric 68*e8d8bef9SDimitry Andric interceptors_initialized = true; 6968d75effSDimitry Andric } 7068d75effSDimitry Andric } // namespace __dfsan 71