#include <assert.h>
#include <elf.h>
#include "sanitizer_common/sanitizer_common.h"
#if SANITIZER_FREEBSD
#include <sys/link_elf.h>
#endif
#include <link.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#if SANITIZER_LINUX
Elf_Phdr;
Elf_Ehdr;
Elf_Addr;
Elf_Sym;
Elf_Dyn;
#elif SANITIZER_FREEBSD
#if SANITIZER_WORDSIZE == 64
#define ElfW64_Dyn …
#define ElfW64_Sym …
#else
#define ElfW32_Dyn …
#define ElfW32_Sym …
#endif
#endif
#include "interception/interception.h"
#include "sanitizer_common/sanitizer_flag_parser.h"
#include "ubsan/ubsan_init.h"
#include "ubsan/ubsan_flags.h"
#ifdef CFI_ENABLE_DIAG
#include "ubsan/ubsan_handlers.h"
#endif
usingnamespace__sanitizer;
namespace __cfi {
#if SANITIZER_LOONGARCH64
#define kCfiShadowLimitsStorageSize …
#else
#define kCfiShadowLimitsStorageSize …
#endif
static union { … } cfi_shadow_limits_storage
__attribute__((aligned …));
static constexpr uptr kShadowGranularity = …;
static constexpr uptr kShadowAlign = …;
static constexpr uint16_t kInvalidShadow = …;
static constexpr uint16_t kUncheckedShadow = …;
uptr GetShadow() { … }
uptr GetShadowSize() { … }
void SetShadowSize(uptr size) { … }
uptr MemToShadowOffset(uptr x) { … }
uint16_t *MemToShadow(uptr x, uptr shadow_base) { … }
CFICheckFn;
class ShadowValue { … };
class ShadowBuilder { … };
void ShadowBuilder::Start() { … }
void ShadowBuilder::AddUnchecked(uptr begin, uptr end) { … }
void ShadowBuilder::Add(uptr begin, uptr end, uptr cfi_check) { … }
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
void ShadowBuilder::Install() { … }
#else
#error not implemented
#endif
uptr find_cfi_check_in_dso(dl_phdr_info *info) { … }
int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *data) { … }
void UpdateShadow() { … }
void InitShadow() { … }
THREADLOCAL int in_loader;
Mutex shadow_update_lock;
void EnterLoader() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { … }
void ExitLoader() SANITIZER_NO_THREAD_SAFETY_ANALYSIS { … }
ALWAYS_INLINE void CfiSlowPathCommon(u64 CallSiteTypeId, void *Ptr,
void *DiagData) { … }
void InitializeFlags() { … }
}
usingnamespace__cfi;
extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
__cfi_slowpath(u64 CallSiteTypeId, void *Ptr) { … }
#ifdef CFI_ENABLE_DIAG
extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
__cfi_slowpath_diag(u64 CallSiteTypeId, void *Ptr, void *DiagData) {
CfiSlowPathCommon(CallSiteTypeId, Ptr, DiagData);
}
#endif
static void EnsureInterceptorsInitialized();
INTERCEPTOR(void*, dlopen, const char *filename, int flag) { … }
INTERCEPTOR(int, dlclose, void *handle) { … }
static Mutex interceptor_init_lock;
static bool interceptors_inited = …;
static void EnsureInterceptorsInitialized() { … }
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
#if !SANITIZER_CAN_USE_PREINIT_ARRAY
__attribute__((constructor(0)))
#endif
void __cfi_init() { … }
#if SANITIZER_CAN_USE_PREINIT_ARRAY
extern "C" {
__attribute__((section(".preinit_array"),
used)) void (*__cfi_preinit)(void) = …;
}
#endif