diff --git a/compiler-rt/lib/msan/tests/msan_test.cpp b/compiler-rt/lib/msan/tests/msan_test.cpp --- a/compiler-rt/lib/msan/tests/msan_test.cpp +++ b/compiler-rt/lib/msan/tests/msan_test.cpp @@ -4679,6 +4679,17 @@ munmap(q, 4096); } +TEST(MemorySanitizer, timer_create) { + struct sigevent sev {}; + sev.sigev_notify = SIGEV_NONE; + timer_t timerid; + int res; + EXPECT_POISONED(timerid); + res = timer_create(CLOCK_REALTIME, &sev, &timerid); + ASSERT_EQ(0, res); + EXPECT_NOT_POISONED(timerid); +} + #if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE TEST(MemorySanitizer, MallocUsableSizeTest) { const size_t kArraySize = 100; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -10211,6 +10211,24 @@ #define INIT___XUNAME #endif +#if SANITIZER_INTERCEPT_TIMER_CREATE +INTERCEPTOR(int, timer_create, __sanitizer_clockid_t clockid, struct sigevent *sevp, __sanitizer_timer_t *timerid) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, timer_create, clockid, sevp, timerid); + // FIXME: under ASan the call below may write to freed memory and corrupt + // its metadata. See + // https://github.com/google/sanitizers/issues/321. + int res = REAL(timer_create)(clockid, sevp, timerid); + if (!res && timerid) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, timerid, sizeof(*timerid)); + } + return res; +} +#define INIT_TIMER_CREATE COMMON_INTERCEPT_FUNCTION(timer_create) +#else +#define INIT_TIMER_CREATE +#endif + #include "sanitizer_common_interceptors_netbsd_compat.inc" static void InitializeCommonInterceptors() { @@ -10529,6 +10547,7 @@ INIT_SIGALTSTACK; INIT_UNAME; INIT___XUNAME; + INIT_TIMER_CREATE; INIT___PRINTF_CHK; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -588,6 +588,7 @@ (SI_POSIX && !(SANITIZER_MAC && SANITIZER_I386)) #define SANITIZER_INTERCEPT_UNAME (SI_POSIX && !SI_FREEBSD) #define SANITIZER_INTERCEPT___XUNAME SI_FREEBSD +#define SANITIZER_INTERCEPT_TIMER_CREATE SI_POSIX #define SANITIZER_INTERCEPT_FLOPEN SI_FREEBSD // This macro gives a way for downstream users to override the above diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -511,9 +511,10 @@ #if SANITIZER_LINUX typedef int __sanitizer_clockid_t; -#endif +typedef void *__sanitizer_timer_t; +# endif -#if SANITIZER_LINUX +# if SANITIZER_LINUX # if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) || \ defined(__mips__) || defined(__hexagon__) typedef unsigned __sanitizer___kernel_uid_t;