From 1fd415fcf5207bdb2154bb65c781c1913e19195c Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 24 Jan 2025 06:28:56 +0000 Subject: [PATCH 1/2] [compiler-rt][rtsan] mremap for Linux interception. --- .../lib/rtsan/rtsan_interceptors_posix.cpp | 28 +++++++++++++++++++ .../tests/rtsan_test_interceptors_posix.cpp | 10 +++++++ 2 files changed, 38 insertions(+) diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index 1b499f2194f21..79fb46bf60397 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -47,6 +47,7 @@ void OSSpinLockLock(volatile OSSpinLock *__lock); #include #include #if SANITIZER_LINUX +#include #include #endif #include @@ -850,6 +851,32 @@ INTERCEPTOR(void *, mmap64, void *addr, size_t length, int prot, int flags, #define RTSAN_MAYBE_INTERCEPT_MMAP64 #endif // SANITIZER_INTERCEPT_MMAP64 +#if SANITIZER_LINUX +// Note that even if rtsan is ported to netbsd, it has a different signature +// still +INTERCEPTOR(void *, mremap, void *oaddr, size_t olength, size_t nlength, + int flags, ...) { + __rtsan_notify_intercepted_call("mremap"); + + void *naddr = nullptr; + + // the last optional argument is only used in this case + // as the new page region will be assigned to. Is ignored otherwise. + if (flags & MREMAP_FIXED) { + va_list args; + + va_start(args, flags); + naddr = va_arg(args, void *); + va_end(args); + } + + return REAL(mremap)(oaddr, olength, nlength, flags, naddr); +} +#define RTSAN_MAYBE_INTERCEPT_MREMAP INTERCEPT_FUNCTION(mremap) +#else +#define RTSAN_MAYBE_INTERCEPT_MREMAP +#endif + INTERCEPTOR(int, munmap, void *addr, size_t length) { __rtsan_notify_intercepted_call("munmap"); return REAL(munmap)(addr, length); @@ -1321,6 +1348,7 @@ void __rtsan::InitializeInterceptors() { INTERCEPT_FUNCTION(posix_memalign); INTERCEPT_FUNCTION(mmap); RTSAN_MAYBE_INTERCEPT_MMAP64; + RTSAN_MAYBE_INTERCEPT_MREMAP; INTERCEPT_FUNCTION(munmap); RTSAN_MAYBE_INTERCEPT_MADVISE; RTSAN_MAYBE_INTERCEPT_POSIX_MADVISE; diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp index a4f2b92b7c494..7bff31e561a85 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp @@ -197,6 +197,16 @@ TEST(TestRtsanInterceptors, MmapDiesWhenRealtime) { ExpectNonRealtimeSurvival(Func); } +#if SANITIZER_LINUX +TEST(TestRtsanInterceptors, MremapDiesWhenRealtime) { + void *addr = mmap(nullptr, 8, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + auto Func = [addr]() { void *_ = mremap(addr, 8, 16, 0); }; + ExpectRealtimeDeath(Func, "mremap"); + ExpectNonRealtimeSurvival(Func); +} +#endif + TEST(TestRtsanInterceptors, MunmapDiesWhenRealtime) { void *ptr = mmap(nullptr, 8, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); From e133beeca49d2b5632924e215d7bdb311add1c81 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 27 Jan 2025 12:36:47 +0000 Subject: [PATCH 2/2] changes from feedback --- compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index 79fb46bf60397..9932fe07d8522 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -852,25 +852,25 @@ INTERCEPTOR(void *, mmap64, void *addr, size_t length, int prot, int flags, #endif // SANITIZER_INTERCEPT_MMAP64 #if SANITIZER_LINUX -// Note that even if rtsan is ported to netbsd, it has a different signature -// still +// Note that even if rtsan is ported to netbsd, it has a slighty different +// and non-variadic signature INTERCEPTOR(void *, mremap, void *oaddr, size_t olength, size_t nlength, int flags, ...) { __rtsan_notify_intercepted_call("mremap"); - void *naddr = nullptr; - // the last optional argument is only used in this case // as the new page region will be assigned to. Is ignored otherwise. if (flags & MREMAP_FIXED) { va_list args; va_start(args, flags); - naddr = va_arg(args, void *); + void *naddr = va_arg(args, void *); va_end(args); + + return REAL(mremap)(oaddr, olength, nlength, flags, naddr); } - return REAL(mremap)(oaddr, olength, nlength, flags, naddr); + return REAL(mremap)(oaddr, olength, nlength, flags); } #define RTSAN_MAYBE_INTERCEPT_MREMAP INTERCEPT_FUNCTION(mremap) #else