| commit 4e1a6c07052b466a2a1cd0c3ff150e4e89a6d87a |
| Author: Nikita Malyavin <nikitamalyavin@gmail.com> |
| Date: Wed Oct 20 16:53:50 2021 -0700 |
| |
| [msan] Add stat-family interceptors on Linux |
| |
| Add following interceptors on Linux: stat, lstat, fstat, fstatat. |
| |
| This fixes use-of-uninitialized value on platforms with GLIBC 2.33+. |
| In particular: Arch Linux, Ubuntu hirsute/impish. |
| |
| The tests should have also been failing during the release on the mentioned platforms, but I cannot find any related discussion. |
| |
| Most likely, the regression was introduced by glibc commit [[ https://github.com/bminor/glibc/commit/8ed005daf0ab03e142500324a34087ce179ae78e | 8ed005daf0ab03e14250032 ]]: |
| all stat-family functions are now exported as shared functions. |
| |
| Before, some of them (namely stat, lstat, fstat, fstatat) were provided as a part of libc_noshared.a and called their __xstat dopplegangers. This is still true for Debian Sid and earlier Ubuntu's. stat interceptors may be safely provided for them, no problem with that. |
| |
| Closes https://github.com/google/sanitizers/issues/1452. |
| See also https://jira.mariadb.org/browse/MDEV-24841 |
| |
| Reviewed By: eugenis |
| |
| Differential Revision: https://reviews.llvm.org/D111984 |
| |
| diff --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp |
| index e61b24fd47ea..830190916ed7 100644 |
| --- a/compiler-rt/lib/msan/msan_interceptors.cpp |
| +++ b/compiler-rt/lib/msan/msan_interceptors.cpp |
| @@ -658,7 +658,8 @@ INTERCEPTOR(int, putenv, char *string) { |
| return res; |
| } |
| |
| -#if SANITIZER_FREEBSD || SANITIZER_NETBSD |
| +#define SANITIZER_STAT_LINUX (SANITIZER_LINUX && __GLIBC_PREREQ(2, 33)) |
| +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_STAT_LINUX |
| INTERCEPTOR(int, fstat, int fd, void *buf) { |
| ENSURE_MSAN_INITED(); |
| int res = REAL(fstat)(fd, buf); |
| @@ -666,7 +667,7 @@ INTERCEPTOR(int, fstat, int fd, void *buf) { |
| __msan_unpoison(buf, __sanitizer::struct_stat_sz); |
| return res; |
| } |
| -#define MSAN_MAYBE_INTERCEPT_FSTAT INTERCEPT_FUNCTION(fstat) |
| +# define MSAN_MAYBE_INTERCEPT_FSTAT MSAN_INTERCEPT_FUNC(fstat) |
| #else |
| #define MSAN_MAYBE_INTERCEPT_FSTAT |
| #endif |
| @@ -679,7 +680,7 @@ INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) { |
| __msan_unpoison(buf, __sanitizer::struct_stat_sz); |
| return res; |
| } |
| -#define MSAN_MAYBE_INTERCEPT___FXSTAT INTERCEPT_FUNCTION(__fxstat) |
| +# define MSAN_MAYBE_INTERCEPT___FXSTAT MSAN_INTERCEPT_FUNC(__fxstat) |
| #else |
| #define MSAN_MAYBE_INTERCEPT___FXSTAT |
| #endif |
| @@ -692,20 +693,24 @@ INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) { |
| __msan_unpoison(buf, __sanitizer::struct_stat64_sz); |
| return res; |
| } |
| -#define MSAN_MAYBE_INTERCEPT___FXSTAT64 INTERCEPT_FUNCTION(__fxstat64) |
| +# define MSAN_MAYBE_INTERCEPT___FXSTAT64 MSAN_INTERCEPT_FUNC(__fxstat64) |
| #else |
| -#define MSAN_MAYBE_INTERCEPT___FXSTAT64 |
| +# define MSAN_MAYBE_INTERCEPT___FXSTAT64 |
| #endif |
| |
| -#if SANITIZER_FREEBSD || SANITIZER_NETBSD |
| +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_STAT_LINUX |
| INTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) { |
| ENSURE_MSAN_INITED(); |
| int res = REAL(fstatat)(fd, pathname, buf, flags); |
| if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz); |
| return res; |
| } |
| -# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(fstatat) |
| +# define MSAN_MAYBE_INTERCEPT_FSTATAT MSAN_INTERCEPT_FUNC(fstatat) |
| #else |
| +# define MSAN_MAYBE_INTERCEPT_FSTATAT |
| +#endif |
| + |
| +#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD |
| INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf, |
| int flags) { |
| ENSURE_MSAN_INITED(); |
| @@ -713,7 +718,9 @@ INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf, |
| if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz); |
| return res; |
| } |
| -# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(__fxstatat) |
| +# define MSAN_MAYBE_INTERCEPT___FXSTATAT MSAN_INTERCEPT_FUNC(__fxstatat) |
| +#else |
| +# define MSAN_MAYBE_INTERCEPT___FXSTATAT |
| #endif |
| |
| #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD |
| @@ -724,9 +731,9 @@ INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf, |
| if (!res) __msan_unpoison(buf, __sanitizer::struct_stat64_sz); |
| return res; |
| } |
| -#define MSAN_MAYBE_INTERCEPT___FXSTATAT64 INTERCEPT_FUNCTION(__fxstatat64) |
| +# define MSAN_MAYBE_INTERCEPT___FXSTATAT64 MSAN_INTERCEPT_FUNC(__fxstatat64) |
| #else |
| -#define MSAN_MAYBE_INTERCEPT___FXSTATAT64 |
| +# define MSAN_MAYBE_INTERCEPT___FXSTATAT64 |
| #endif |
| |
| INTERCEPTOR(int, pipe, int pipefd[2]) { |
| @@ -1690,7 +1697,8 @@ void InitializeInterceptors() { |
| MSAN_MAYBE_INTERCEPT_FCVT; |
| MSAN_MAYBE_INTERCEPT_FSTAT; |
| MSAN_MAYBE_INTERCEPT___FXSTAT; |
| - MSAN_INTERCEPT_FSTATAT; |
| + MSAN_MAYBE_INTERCEPT_FSTATAT; |
| + MSAN_MAYBE_INTERCEPT___FXSTATAT; |
| MSAN_MAYBE_INTERCEPT___FXSTAT64; |
| MSAN_MAYBE_INTERCEPT___FXSTATAT64; |
| INTERCEPT_FUNCTION(pipe); |
| diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h |
| index 4e6efcad44d1..4da53ca1ab98 100644 |
| --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h |
| +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h |
| @@ -460,10 +460,13 @@ |
| #define SANITIZER_INTERCEPT_SEND_SENDTO SI_POSIX |
| #define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE SI_LINUX |
| |
| -#define SANITIZER_INTERCEPT_STAT \ |
| - (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS) |
| +#define SI_STAT_LINUX (SI_LINUX && __GLIBC_PREREQ(2, 33)) |
| +#define SANITIZER_INTERCEPT_STAT \ |
| + (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS || \ |
| + SI_STAT_LINUX) |
| #define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD) |
| -#define SANITIZER_INTERCEPT___XSTAT (!SANITIZER_INTERCEPT_STAT && SI_POSIX) |
| +#define SANITIZER_INTERCEPT___XSTAT \ |
| + (!SANITIZER_INTERCEPT_STAT && SI_POSIX) || SI_STAT_LINUX |
| #define SANITIZER_INTERCEPT___XSTAT64 SI_LINUX_NOT_ANDROID |
| #define SANITIZER_INTERCEPT___LXSTAT SANITIZER_INTERCEPT___XSTAT |
| #define SANITIZER_INTERCEPT___LXSTAT64 SI_LINUX_NOT_ANDROID |