brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · f900ae6 Raw
84 lines · cpp
1//===-- interception_linux.cpp ----------------------------------*- C++ -*-===//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 AddressSanitizer, an address sanity checker.10//11// Linux-specific interception methods.12//===----------------------------------------------------------------------===//13 14#include "interception.h"15 16#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \17    SANITIZER_SOLARIS || SANITIZER_HAIKU18 19#include <dlfcn.h>   // for dlsym() and dlvsym()20 21namespace __interception {22 23#if SANITIZER_NETBSD24static int StrCmp(const char *s1, const char *s2) {25  while (true) {26    if (*s1 != *s2)27      return false;28    if (*s1 == 0)29      return true;30    s1++;31    s2++;32  }33}34#endif35 36static void *GetFuncAddr(const char *name, uptr trampoline) {37#if SANITIZER_NETBSD38  // FIXME: Find a better way to handle renames39  if (StrCmp(name, "sigaction"))40    name = "__sigaction14";41#endif42  void *addr = dlsym(RTLD_NEXT, name);43  if (!addr) {44    // If the lookup using RTLD_NEXT failed, the sanitizer runtime library is45    // later in the library search order than the DSO that we are trying to46    // intercept, which means that we cannot intercept this function. We still47    // want the address of the real definition, though, so look it up using48    // RTLD_DEFAULT.49    addr = dlsym(RTLD_DEFAULT, name);50 51    // In case `name' is not loaded, dlsym ends up finding the actual wrapper.52    // We don't want to intercept the wrapper and have it point to itself.53    if ((uptr)addr == trampoline)54      addr = nullptr;55  }56  return addr;57}58 59bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,60                       uptr trampoline) {61  void *addr = GetFuncAddr(name, trampoline);62  *ptr_to_real = (uptr)addr;63  return addr && (func == trampoline);64}65 66// dlvsym is a GNU extension supported by some other platforms.67#if SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD68static void *GetFuncAddr(const char *name, const char *ver) {69  return dlvsym(RTLD_NEXT, name, ver);70}71 72bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,73                       uptr func, uptr trampoline) {74  void *addr = GetFuncAddr(name, ver);75  *ptr_to_real = (uptr)addr;76  return addr && (func == trampoline);77}78#  endif  // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD79 80}  // namespace __interception81 82#endif  // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||83        // SANITIZER_SOLARIS || SANITIZER_HAIKU84