forked from OSchip/llvm-project
sanitizer_common: Introduce internal_madvise and start using it.
A recent change to sanitizer_common caused us to issue the syscall madvise(MADV_HUGEPAGE) during HWASAN initialization. This may lead to a problem if madvise is instrumented (e.g. because libc is instrumented or the user intercepted it). For example, on Android the syscall may fail if the kernel does not support transparent hugepages, which leads to an attempt to set errno in a HWASAN instrumented function. Avoid this problem by introducing a syscall wrapper and using it to issue this syscall. Tested only on Linux; includes untested updates for the other platforms. Differential Revision: https://reviews.llvm.org/D85870
This commit is contained in:
parent
114c9fa0e4
commit
9f8c4039f2
|
@ -187,6 +187,10 @@ uptr internal_munmap(void *addr, uptr length) {
|
|||
int internal_mprotect(void *addr, uptr length, int prot) {
|
||||
return internal_syscall(SYSCALL(mprotect), (uptr)addr, length, prot);
|
||||
}
|
||||
|
||||
int internal_madvise(uptr addr, uptr length, int advice) {
|
||||
return internal_syscall(SYSCALL(madvise), addr, length, advice);
|
||||
}
|
||||
#endif
|
||||
|
||||
uptr internal_close(fd_t fd) {
|
||||
|
|
|
@ -137,6 +137,10 @@ int internal_mprotect(void *addr, uptr length, int prot) {
|
|||
return mprotect(addr, length, prot);
|
||||
}
|
||||
|
||||
int internal_madvise(uptr addr, uptr length, int advice) {
|
||||
return madvise((void *)addr, length, advice);
|
||||
}
|
||||
|
||||
uptr internal_close(fd_t fd) {
|
||||
return close(fd);
|
||||
}
|
||||
|
|
|
@ -110,6 +110,11 @@ int internal_mprotect(void *addr, uptr length, int prot) {
|
|||
return _REAL(mprotect, addr, length, prot);
|
||||
}
|
||||
|
||||
int internal_madvise(uptr addr, uptr length, int advice) {
|
||||
DEFINE__REAL(int, madvise, void *a, uptr b, int c);
|
||||
return _REAL(madvise, (void *)addr, length, advice);
|
||||
}
|
||||
|
||||
uptr internal_close(fd_t fd) {
|
||||
CHECK(&_sys_close);
|
||||
return _sys_close(fd);
|
||||
|
|
|
@ -52,6 +52,10 @@ int internal_mprotect(void *addr, uptr length, int prot) {
|
|||
return mprotect(addr, length, prot);
|
||||
}
|
||||
|
||||
int internal_madvise(uptr addr, uptr length, int advice) {
|
||||
return madvise((void *)addr, length, advice);
|
||||
}
|
||||
|
||||
int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
|
||||
const void *newp, uptr newlen) {
|
||||
Printf("internal_sysctlbyname not implemented for OpenBSD");
|
||||
|
|
|
@ -42,6 +42,7 @@ uptr internal_mmap(void *addr, uptr length, int prot, int flags,
|
|||
int fd, u64 offset);
|
||||
uptr internal_munmap(void *addr, uptr length);
|
||||
int internal_mprotect(void *addr, uptr length, int prot);
|
||||
int internal_madvise(uptr addr, uptr length, int advice);
|
||||
|
||||
// OS
|
||||
uptr internal_filesize(fd_t fd); // -1 on error.
|
||||
|
|
|
@ -44,12 +44,6 @@
|
|||
#define MAP_NORESERVE 0
|
||||
#endif
|
||||
|
||||
#if SANITIZER_SOLARIS
|
||||
// Illumos' declaration of madvie cannot be made visible if _XOPEN_SOURCE
|
||||
// is defined as g++ does on Solaris.
|
||||
extern "C" int madvise(void *, size_t, int);
|
||||
#endif
|
||||
|
||||
typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
|
||||
|
||||
namespace __sanitizer {
|
||||
|
@ -67,27 +61,24 @@ void ReleaseMemoryPagesToOS(uptr beg, uptr end) {
|
|||
uptr beg_aligned = RoundUpTo(beg, page_size);
|
||||
uptr end_aligned = RoundDownTo(end, page_size);
|
||||
if (beg_aligned < end_aligned)
|
||||
// In the default Solaris compilation environment, madvise() is declared
|
||||
// to take a caddr_t arg; casting it to void * results in an invalid
|
||||
// conversion error, so use char * instead.
|
||||
madvise((char *)beg_aligned, end_aligned - beg_aligned,
|
||||
SANITIZER_MADVISE_DONTNEED);
|
||||
internal_madvise(beg_aligned, end_aligned - beg_aligned,
|
||||
SANITIZER_MADVISE_DONTNEED);
|
||||
}
|
||||
|
||||
void SetShadowRegionHugePageMode(uptr addr, uptr size) {
|
||||
#ifdef MADV_NOHUGEPAGE // May not be defined on old systems.
|
||||
if (common_flags()->no_huge_pages_for_shadow)
|
||||
madvise((char *)addr, size, MADV_NOHUGEPAGE);
|
||||
internal_madvise(addr, size, MADV_NOHUGEPAGE);
|
||||
else
|
||||
madvise((char *)addr, size, MADV_HUGEPAGE);
|
||||
internal_madvise(addr, size, MADV_HUGEPAGE);
|
||||
#endif // MADV_NOHUGEPAGE
|
||||
}
|
||||
|
||||
bool DontDumpShadowMemory(uptr addr, uptr length) {
|
||||
#if defined(MADV_DONTDUMP)
|
||||
return madvise((char *)addr, length, MADV_DONTDUMP) == 0;
|
||||
return internal_madvise(addr, length, MADV_DONTDUMP) == 0;
|
||||
#elif defined(MADV_NOCORE)
|
||||
return madvise((char *)addr, length, MADV_NOCORE) == 0;
|
||||
return internal_madvise(addr, length, MADV_NOCORE) == 0;
|
||||
#else
|
||||
return true;
|
||||
#endif // MADV_DONTDUMP
|
||||
|
|
|
@ -74,6 +74,14 @@ DECLARE__REAL_AND_INTERNAL(int, mprotect, void *addr, uptr length, int prot) {
|
|||
return _REAL(mprotect)(addr, length, prot);
|
||||
}
|
||||
|
||||
// Illumos' declaration of madvise cannot be made visible if _XOPEN_SOURCE
|
||||
// is defined as g++ does on Solaris.
|
||||
extern "C" int madvise(caddr_t, size_t, int);
|
||||
|
||||
int internal_madvise(uptr addr, uptr length, int advice) {
|
||||
return madvise((caddr_t)addr, length, advice);
|
||||
}
|
||||
|
||||
DECLARE__REAL_AND_INTERNAL(uptr, close, fd_t fd) {
|
||||
return _REAL(close)(fd);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue