From 1af59ba88bf3bd65dbf534fb498b8636eb09a728 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Mon, 14 Oct 2024 20:46:45 -0700 Subject: [PATCH] [Sanitizers] Intercept timer_create (#112285) --- .../lib/hwasan/hwasan_platform_interceptors.h | 3 +++ compiler-rt/lib/msan/tests/msan_test.cpp | 23 +++++++++++++++++++ .../sanitizer_common_interceptors.inc | 19 +++++++++++++++ .../sanitizer_platform_interceptors.h | 3 +++ .../sanitizer_platform_limits_posix.h | 4 ++++ 5 files changed, 52 insertions(+) diff --git a/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h b/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h index d92b5105219427..e8011014c2331d 100644 --- a/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h +++ b/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h @@ -200,6 +200,9 @@ #undef SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID #define SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID 0 +#undef SANITIZER_INTERCEPT_TIMER_CREATE +#define SANITIZER_INTERCEPT_TIMER_CREATE 0 + #undef SANITIZER_INTERCEPT_GETITIMER #define SANITIZER_INTERCEPT_GETITIMER 0 diff --git a/compiler-rt/lib/msan/tests/msan_test.cpp b/compiler-rt/lib/msan/tests/msan_test.cpp index 41b99fabe84f47..ad265acf4c1e39 100644 --- a/compiler-rt/lib/msan/tests/msan_test.cpp +++ b/compiler-rt/lib/msan/tests/msan_test.cpp @@ -4881,4 +4881,27 @@ TEST(MemorySanitizer, throw_catch) { // pass } } + +#if defined(__linux__) +TEST(MemorySanitizer, timer_create) { + timer_t timer; + EXPECT_POISONED(timer); + int res = timer_create(CLOCK_REALTIME, nullptr, &timer); + ASSERT_EQ(0, res); + EXPECT_NOT_POISONED(timer); + + // Make sure the timer is usable. + struct itimerspec cur_value {}; + cur_value.it_value.tv_sec = 1; + EXPECT_EQ(0, timer_settime(timer, 0, &cur_value, nullptr)); + + timer_t timer2; + EXPECT_POISONED(timer2); + // Use an invalid clock_id to make timer_create fail. + res = timer_create(INT_MAX, nullptr, &timer2); + ASSERT_EQ(-1, res); + EXPECT_POISONED(timer2); + timer_delete(timer); +} +#endif } // namespace diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index b8627f8557afe2..211f9f70d7e4c6 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2289,6 +2289,24 @@ INTERCEPTOR(int, pthread_getcpuclockid, uptr thread, #define INIT_CLOCK_GETCPUCLOCKID #endif +#if SANITIZER_INTERCEPT_TIMER_CREATE +INTERCEPTOR(int, timer_create, __sanitizer_clockid_t clockid, void *sevp, + __sanitizer_timer_t *timer) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, timer_create, clockid, sevp, timer); + int res = REAL(timer_create)(clockid, sevp, timer); + if (!res && timer) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, timer, sizeof *timer); + } + return res; +} + +# define INIT_TIMER_CREATE \ + COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_create, "GLIBC_2.3.3"); +#else +# define INIT_TIMER_CREATE +#endif + #if SANITIZER_INTERCEPT_GETITIMER INTERCEPTOR(int, getitimer, int which, void *curr_value) { void *ctx; @@ -10266,6 +10284,7 @@ static void InitializeCommonInterceptors() { INIT_SETPWENT; INIT_CLOCK_GETTIME; INIT_CLOCK_GETCPUCLOCKID; + INIT_TIMER_CREATE; INIT_GETITIMER; INIT_TIME; INIT_GLOB; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 6959a6d52d604e..36fafdc642642b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -237,6 +237,9 @@ (SI_FREEBSD || SI_NETBSD || SI_LINUX || SI_SOLARIS) #define SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID \ (SI_LINUX || SI_FREEBSD || SI_NETBSD) +// TODO: This should be SI_POSIX, adding Linux first until I have time +// to verify all timer_t typedefs on other platforms. +#define SANITIZER_INTERCEPT_TIMER_CREATE SI_LINUX #define SANITIZER_INTERCEPT_GETITIMER SI_POSIX #define SANITIZER_INTERCEPT_TIME SI_POSIX #define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index e8c81aa8e28163..b4ccf7b3d7bef4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -1517,6 +1517,10 @@ extern const int si_SEGV_ACCERR; #define SIGACTION_SYMNAME sigaction +# if SANITIZER_LINUX +typedef void *__sanitizer_timer_t; +# endif + #endif // SANITIZER_LINUX || SANITIZER_APPLE #endif