diff --git a/compiler-rt/include/sanitizer/linux_syscall_hooks.h b/compiler-rt/include/sanitizer/linux_syscall_hooks.h --- a/compiler-rt/include/sanitizer/linux_syscall_hooks.h +++ b/compiler-rt/include/sanitizer/linux_syscall_hooks.h @@ -1225,6 +1225,16 @@ __sanitizer_syscall_post_impl_epoll_pwait( \ res, (long)(epfd), (long)(events), (long)(maxevents), (long)(timeout), \ (long)(sigmask), (long)(sigsetsize)) +#define __sanitizer_syscall_pre_epoll_pwait2(epfd, events, maxevents, timeout, \ + sigmask, sigsetsize) \ + __sanitizer_syscall_pre_impl_epoll_pwait2( \ + (long)(epfd), (long)(events), (long)(maxevents), (long)(timeout), \ + (long)(sigmask), (long)(sigsetsize)) +#define __sanitizer_syscall_post_epoll_pwait2(res, epfd, events, maxevents, \ + timeout, sigmask, sigsetsize) \ + __sanitizer_syscall_post_impl_epoll_pwait2( \ + res, (long)(epfd), (long)(events), (long)(maxevents), (long)(timeout), \ + (long)(sigmask), (long)(sigsetsize)) #define __sanitizer_syscall_pre_gethostname(name, len) \ __sanitizer_syscall_pre_impl_gethostname((long)(name), (long)(len)) #define __sanitizer_syscall_post_gethostname(res, name, len) \ @@ -2696,6 +2706,13 @@ void __sanitizer_syscall_post_impl_epoll_pwait(long res, long epfd, long events, long maxevents, long timeout, long sigmask, long sigsetsize); +void __sanitizer_syscall_pre_impl_epoll_pwait2(long epfd, long events, + long maxevents, long timeout, + long sigmask, long sigsetsize); +void __sanitizer_syscall_post_impl_epoll_pwait2(long res, long epfd, + long events, long maxevents, + long timeout, long sigmask, + long sigsetsize); void __sanitizer_syscall_pre_impl_gethostname(long name, long len); void __sanitizer_syscall_post_impl_gethostname(long res, long name, long len); void __sanitizer_syscall_pre_impl_sethostname(long name, long len); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc @@ -2127,6 +2127,26 @@ } } +PRE_SYSCALL(epoll_pwait2) +(long epfd, void *events, long maxevents, + const sanitizer_kernel_timespec *timeout, const kernel_sigset_t *sigmask, + long sigsetsize) { + if (timeout) + PRE_READ(timeout, sizeof(timeout)); + if (sigmask) + PRE_READ(sigmask, sigsetsize); +} + +POST_SYSCALL(epoll_pwait2) +(long res, long epfd, void *events, long maxevents, + const sanitizer_kernel_timespec *timeout, const void *sigmask, + long sigsetsize) { + if (res >= 0) { + if (events) + POST_WRITE(events, res * struct_epoll_event_sz); + } +} + PRE_SYSCALL(gethostname)(void *name, long len) {} POST_SYSCALL(gethostname)(long res, void *name, long len) { diff --git a/compiler-rt/test/msan/Linux/syscalls.cpp b/compiler-rt/test/msan/Linux/syscalls.cpp --- a/compiler-rt/test/msan/Linux/syscalls.cpp +++ b/compiler-rt/test/msan/Linux/syscalls.cpp @@ -141,5 +141,14 @@ __sanitizer_syscall_post_epoll_pwait(max_events, 0, buf, max_events, 0, &sigset, sizeof(sigset)); assert(__msan_test_shadow(buf, sizeof(buf)) == max_events * sizeof(epoll_event)); + __msan_poison(buf, sizeof(buf)); + sigset = {}; + timespec timespec = {}; + __sanitizer_syscall_pre_epoll_pwait2(0, buf, max_events, ×pec, + &sigset, sizeof(sigset)); + __sanitizer_syscall_post_epoll_pwait2(max_events, 0, buf, max_events, + ×pec, &sigset, sizeof(sigset)); + assert(__msan_test_shadow(buf, sizeof(buf)) == max_events * sizeof(epoll_event)); + return 0; }