Skip to content

Commit 61e50b9

Browse files
authored
[rtsan] Added mmap and shm interceptors (#114862)
# Why do we think these are unsafe? mmap and munmap are used for mapping a specific manipulation of the virtual memory of a process. Typically used in things like databases and area allocators. They call the system calls `mmap` and `munmap` under the hood (confirmed on mac using dtrace) shm_open/unlink interact with shared memory across processes. Similarly under the hood, they call the `shm_open`/`shm_unlink` system calls (confirmed on mac using dtrace)
1 parent be64ca9 commit 61e50b9

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,38 @@ INTERCEPTOR(void *, pvalloc, size_t size) {
504504
}
505505
#endif
506506

507+
INTERCEPTOR(void *, mmap, void *addr, size_t length, int prot, int flags,
508+
int fd, off_t offset) {
509+
__rtsan_notify_intercepted_call("mmap");
510+
return REAL(mmap)(addr, length, prot, flags, fd, offset);
511+
}
512+
513+
#if SANITIZER_INTERCEPT_MMAP64
514+
INTERCEPTOR(void *, mmap64, void *addr, size_t length, int prot, int flags,
515+
int fd, off64_t offset) {
516+
__rtsan_notify_intercepted_call("mmap64");
517+
return REAL(mmap64)(addr, length, prot, flags, fd, offset);
518+
}
519+
#define RTSAN_MAYBE_INTERCEPT_MMAP64 INTERCEPT_FUNCTION(mmap64)
520+
#else
521+
#define RTSAN_MAYBE_INTERCEPT_MMAP64
522+
#endif // SANITIZER_INTERCEPT_MMAP64
523+
524+
INTERCEPTOR(int, munmap, void *addr, size_t length) {
525+
__rtsan_notify_intercepted_call("munmap");
526+
return REAL(munmap)(addr, length);
527+
}
528+
529+
INTERCEPTOR(int, shm_open, const char *name, int oflag, mode_t mode) {
530+
__rtsan_notify_intercepted_call("shm_open");
531+
return REAL(shm_open)(name, oflag, mode);
532+
}
533+
534+
INTERCEPTOR(int, shm_unlink, const char *name) {
535+
__rtsan_notify_intercepted_call("shm_unlink");
536+
return REAL(shm_unlink)(name);
537+
}
538+
507539
// Sockets
508540
INTERCEPTOR(int, socket, int domain, int type, int protocol) {
509541
__rtsan_notify_intercepted_call("socket");
@@ -558,6 +590,11 @@ void __rtsan::InitializeInterceptors() {
558590
INTERCEPT_FUNCTION(valloc);
559591
RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC;
560592
INTERCEPT_FUNCTION(posix_memalign);
593+
INTERCEPT_FUNCTION(mmap);
594+
RTSAN_MAYBE_INTERCEPT_MMAP64;
595+
INTERCEPT_FUNCTION(munmap);
596+
INTERCEPT_FUNCTION(shm_open);
597+
INTERCEPT_FUNCTION(shm_unlink);
561598
#if SANITIZER_INTERCEPT_MEMALIGN
562599
INTERCEPT_FUNCTION(memalign);
563600
#endif

compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <fcntl.h>
3737
#include <pthread.h>
3838
#include <stdio.h>
39+
#include <sys/mman.h>
3940
#include <sys/socket.h>
4041
#include <sys/uio.h>
4142

@@ -47,6 +48,7 @@ const char *const kOpenAtFunctionName = "openat64";
4748
const char *const kOpenFunctionName = "open64";
4849
const char *const kPreadFunctionName = "pread64";
4950
const char *const kPwriteFunctionName = "pwrite64";
51+
const char *const kMmapFunctionName = "mmap64";
5052
#else
5153
const char *const kCreatFunctionName = "creat";
5254
const char *const kFcntlFunctionName = "fcntl";
@@ -55,6 +57,7 @@ const char *const kOpenAtFunctionName = "openat";
5557
const char *const kOpenFunctionName = "open";
5658
const char *const kPreadFunctionName = "pread";
5759
const char *const kPwriteFunctionName = "pwrite";
60+
const char *const kMmapFunctionName = "mmap";
5861
#endif
5962

6063
using namespace testing;
@@ -179,6 +182,37 @@ TEST(TestRtsanInterceptors, PvallocDiesWhenRealtime) {
179182
}
180183
#endif
181184

185+
TEST(TestRtsanInterceptors, MmapDiesWhenRealtime) {
186+
auto Func = []() {
187+
void *_ = mmap(nullptr, 8, PROT_READ | PROT_WRITE,
188+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
189+
};
190+
ExpectRealtimeDeath(Func, kMmapFunctionName);
191+
ExpectNonRealtimeSurvival(Func);
192+
}
193+
194+
TEST(TestRtsanInterceptors, MunmapDiesWhenRealtime) {
195+
void *ptr = mmap(nullptr, 8, PROT_READ | PROT_WRITE,
196+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
197+
EXPECT_NE(ptr, nullptr);
198+
auto Func = [ptr]() { munmap(ptr, 8); };
199+
printf("Right before death munmap\n");
200+
ExpectRealtimeDeath(Func, "munmap");
201+
ExpectNonRealtimeSurvival(Func);
202+
}
203+
204+
TEST(TestRtsanInterceptors, ShmOpenDiesWhenRealtime) {
205+
auto Func = []() { shm_open("/rtsan_test_shm", O_CREAT | O_RDWR, 0); };
206+
ExpectRealtimeDeath(Func, "shm_open");
207+
ExpectNonRealtimeSurvival(Func);
208+
}
209+
210+
TEST(TestRtsanInterceptors, ShmUnlinkDiesWhenRealtime) {
211+
auto Func = []() { shm_unlink("/rtsan_test_shm"); };
212+
ExpectRealtimeDeath(Func, "shm_unlink");
213+
ExpectNonRealtimeSurvival(Func);
214+
}
215+
182216
/*
183217
Sleeping
184218
*/

0 commit comments

Comments
 (0)