Path: blob/main/contrib/llvm-project/compiler-rt/lib/safestack/safestack_platform.h
35260 views
//===-- safestack_platform.h ----------------------------------------------===//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 implements platform specific parts of SafeStack runtime.9// Don't use equivalent functionality from sanitizer_common to avoid dragging10// a large codebase into security sensitive code.11//12//===----------------------------------------------------------------------===//1314#ifndef SAFESTACK_PLATFORM_H15#define SAFESTACK_PLATFORM_H1617#include "safestack_util.h"18#include "sanitizer_common/sanitizer_platform.h"1920#include <dlfcn.h>21#include <errno.h>22#include <stdint.h>23#include <stdio.h>24#include <stdlib.h>25#include <sys/mman.h>26#include <sys/syscall.h>27#include <sys/types.h>28#include <unistd.h>2930#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX || \31SANITIZER_SOLARIS)32# error "Support for your platform has not been implemented"33#endif3435#if SANITIZER_NETBSD36#include <lwp.h>3738extern "C" void *__mmap(void *, size_t, int, int, int, int, off_t);39#endif4041#if SANITIZER_FREEBSD42#include <sys/thr.h>43#endif4445#if SANITIZER_SOLARIS46# include <thread.h>47#endif4849// Keep in sync with sanitizer_linux.cpp.50//51// Are we using 32-bit or 64-bit Linux syscalls?52// x32 (which defines __x86_64__) has SANITIZER_WORDSIZE == 3253// but it still needs to use 64-bit syscalls.54#if SANITIZER_LINUX && \55(defined(__x86_64__) || defined(__powerpc64__) || \56SANITIZER_WORDSIZE == 64 || (defined(__mips__) && _MIPS_SIM == _ABIN32))57# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 158#else59# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 060#endif6162namespace safestack {6364#if SANITIZER_NETBSD65static void *GetRealLibcAddress(const char *symbol) {66void *real = dlsym(RTLD_NEXT, symbol);67if (!real)68real = dlsym(RTLD_DEFAULT, symbol);69if (!real) {70fprintf(stderr, "safestack GetRealLibcAddress failed for symbol=%s",71symbol);72abort();73}74return real;75}7677#define _REAL(func, ...) real##_##func(__VA_ARGS__)78#define DEFINE__REAL(ret_type, func, ...) \79static ret_type (*real_##func)(__VA_ARGS__) = NULL; \80if (!real_##func) { \81real_##func = (ret_type(*)(__VA_ARGS__))GetRealLibcAddress(#func); \82} \83SFS_CHECK(real_##func);84#endif8586#if SANITIZER_SOLARIS87# define _REAL(func) _##func88# define DEFINE__REAL(ret_type, func, ...) \89extern "C" ret_type _REAL(func)(__VA_ARGS__)9091# if !defined(_LP64) && _FILE_OFFSET_BITS == 6492# define _REAL64(func) _##func##6493# else94# define _REAL64(func) _REAL(func)95# endif96# define DEFINE__REAL64(ret_type, func, ...) \97extern "C" ret_type _REAL64(func)(__VA_ARGS__)9899DEFINE__REAL64(void *, mmap, void *a, size_t b, int c, int d, int e, off_t f);100DEFINE__REAL(int, munmap, void *a, size_t b);101DEFINE__REAL(int, mprotect, void *a, size_t b, int c);102#endif103104using ThreadId = uint64_t;105106inline ThreadId GetTid() {107#if SANITIZER_NETBSD108DEFINE__REAL(int, _lwp_self);109return _REAL(_lwp_self);110#elif SANITIZER_FREEBSD111long Tid;112thr_self(&Tid);113return Tid;114#elif SANITIZER_SOLARIS115return thr_self();116#else117return syscall(SYS_gettid);118#endif119}120121inline int TgKill(pid_t pid, ThreadId tid, int sig) {122#if SANITIZER_NETBSD123DEFINE__REAL(int, _lwp_kill, int a, int b);124(void)pid;125return _REAL(_lwp_kill, tid, sig);126#elif SANITIZER_SOLARIS127(void)pid;128errno = thr_kill(tid, sig);129// TgKill is expected to return -1 on error, not an errno.130return errno != 0 ? -1 : 0;131#elif SANITIZER_FREEBSD132return syscall(SYS_thr_kill2, pid, tid, sig);133#else134// tid is pid_t (int), not ThreadId (uint64_t).135return syscall(SYS_tgkill, pid, (pid_t)tid, sig);136#endif137}138139inline void *Mmap(void *addr, size_t length, int prot, int flags, int fd,140off_t offset) {141#if SANITIZER_NETBSD142return __mmap(addr, length, prot, flags, fd, 0, offset);143#elif SANITIZER_FREEBSD && (defined(__aarch64__) || defined(__x86_64__))144return (void *)__syscall(SYS_mmap, addr, length, prot, flags, fd, offset);145#elif SANITIZER_FREEBSD && (defined(__i386__))146return (void *)syscall(SYS_mmap, addr, length, prot, flags, fd, offset);147#elif SANITIZER_SOLARIS148return _REAL64(mmap)(addr, length, prot, flags, fd, offset);149#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS150return (void *)syscall(SYS_mmap, addr, length, prot, flags, fd, offset);151#else152// mmap2 specifies file offset in 4096-byte units.153SFS_CHECK(IsAligned(offset, 4096));154return (void *)syscall(SYS_mmap2, addr, length, prot, flags, fd,155offset / 4096);156#endif157}158159inline int Munmap(void *addr, size_t length) {160#if SANITIZER_NETBSD161DEFINE__REAL(int, munmap, void *a, size_t b);162return _REAL(munmap, addr, length);163#elif SANITIZER_SOLARIS164return _REAL(munmap)(addr, length);165#else166return syscall(SYS_munmap, addr, length);167#endif168}169170inline int Mprotect(void *addr, size_t length, int prot) {171#if SANITIZER_NETBSD172DEFINE__REAL(int, mprotect, void *a, size_t b, int c);173return _REAL(mprotect, addr, length, prot);174#elif SANITIZER_SOLARIS175return _REAL(mprotect)(addr, length, prot);176#else177return syscall(SYS_mprotect, addr, length, prot);178#endif179}180181} // namespace safestack182183#endif // SAFESTACK_PLATFORM_H184185186