From acf0a6428681dccac803984bfbb1e3e54248f090 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Fri, 2 Jul 2021 02:42:38 +0200 Subject: [PATCH] [sanitizer] Fix __sanitizer_kernel_sigset_t endianness issue setuid(0) hangs on SystemZ under TSan because TSan's BackgroundThread ignores SIGSETXID. This in turn happens because internal_sigdelset() messes up the mask bits on big-endian system due to how __sanitizer_kernel_sigset_t is defined. Commit d9a1a53b8d80 ("[ESan] [MIPS] Fix workingset-signal-posix.cpp on MIPS") fixed this for MIPS by adjusting the __sanitizer_kernel_sigset_t definition. Generalize this by defining __SANITIZER_KERNEL_NSIG based on kernel's _NSIG and using uptr[] for __sanitizer_kernel_sigset_t.sig on all platforms. Reviewed By: dvyukov Differential Revision: https://reviews.llvm.org/D105629 --- compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp | 4 ++-- .../lib/sanitizer_common/sanitizer_platform_limits_posix.h | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index cc4dfd7..ac0bb95 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -878,7 +878,7 @@ void internal_sigdelset(__sanitizer_sigset_t *set, int signum) { __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set; const uptr idx = signum / (sizeof(k_set->sig[0]) * 8); const uptr bit = signum % (sizeof(k_set->sig[0]) * 8); - k_set->sig[idx] &= ~(1 << bit); + k_set->sig[idx] &= ~((uptr)1 << bit); } bool internal_sigismember(__sanitizer_sigset_t *set, int signum) { @@ -888,7 +888,7 @@ bool internal_sigismember(__sanitizer_sigset_t *set, int signum) { __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set; const uptr idx = signum / (sizeof(k_set->sig[0]) * 8); const uptr bit = signum % (sizeof(k_set->sig[0]) * 8); - return k_set->sig[idx] & (1 << bit); + return k_set->sig[idx] & ((uptr)1 << bit); } #elif SANITIZER_FREEBSD void internal_sigdelset(__sanitizer_sigset_t *set, int signum) { 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 8a156b7..4dd2764 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -650,14 +650,14 @@ struct __sanitizer_sigaction { #endif // !SANITIZER_ANDROID #if defined(__mips__) -struct __sanitizer_kernel_sigset_t { - uptr sig[2]; -}; +#define __SANITIZER_KERNEL_NSIG 128 #else +#define __SANITIZER_KERNEL_NSIG 64 +#endif + struct __sanitizer_kernel_sigset_t { - u8 sig[8]; + uptr sig[__SANITIZER_KERNEL_NSIG / (sizeof(uptr) * 8)]; }; -#endif // Linux system headers define the 'sa_handler' and 'sa_sigaction' macros. #if SANITIZER_MIPS -- 2.7.4