diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 4e653fa266de..74b098c562e0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -5194,6 +5194,31 @@ INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) { #define INIT_SEM #endif // SANITIZER_INTERCEPT_SEM +#if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL +INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate); + int res = REAL(pthread_setcancelstate)(state, oldstate); + if (res == 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate)); + return res; +} + +INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype); + int res = REAL(pthread_setcanceltype)(type, oldtype); + if (res == 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype)); + return res; +} +#define INIT_PTHREAD_SETCANCEL \ + COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate); \ + COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype); +#else +#define INIT_PTHREAD_SETCANCEL +#endif + static void InitializeCommonInterceptors() { static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap(); @@ -5365,4 +5390,5 @@ static void InitializeCommonInterceptors() { INIT_MLOCKX; INIT_FOPENCOOKIE; INIT_SEM; + INIT_PTHREAD_SETCANCEL; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index af6969bef87b..15461bfc5789 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -257,6 +257,7 @@ #define SANITIZER_INTERCEPT_MLOCKX SI_NOT_WINDOWS #define SANITIZER_INTERCEPT_FOPENCOOKIE SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_SEM SI_LINUX || SI_FREEBSD +#define SANITIZER_INTERCEPT_PTHREAD_SETCANCEL SI_NOT_WINDOWS #define SANITIZER_INTERCEPTOR_HOOKS SI_LINUX diff --git a/compiler-rt/test/msan/pthread_setcancelstate.cc b/compiler-rt/test/msan/pthread_setcancelstate.cc new file mode 100644 index 000000000000..087c2223a83d --- /dev/null +++ b/compiler-rt/test/msan/pthread_setcancelstate.cc @@ -0,0 +1,19 @@ +// RUN: %clangxx_msan -O0 %s -o %t && %run %t + +#include +#include +#include + +int main(void) { + int oldstate; + int oldtype; + int res = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); + assert(res == 0); + __msan_check_mem_is_initialized(&oldstate, sizeof(oldstate)); + + res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); + assert(res == 0); + __msan_check_mem_is_initialized(&oldtype, sizeof(oldtype)); + + return 0; +}