diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 16bdffe4c21184..9975f5321a59b2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -9550,6 +9550,21 @@ INTERCEPTOR(void, sl_free, void *sl, int freeall) { #define INIT_SL_INIT #endif +#if SANITIZER_INTERCEPT_GETRANDOM +INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getrandom, buf, buflen, flags); + SSIZE_T n = REAL(getrandom)(buf, buflen, flags); + if (n > 0) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, n); + } + return n; +} +#define INIT_GETRANDOM COMMON_INTERCEPT_FUNCTION(getrandom) +#else +#define INIT_GETRANDOM +#endif + static void InitializeCommonInterceptors() { #if SI_POSIX static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; @@ -9848,6 +9863,7 @@ static void InitializeCommonInterceptors() { INIT_FDEVNAME; INIT_GETUSERSHELL; INIT_SL_INIT; + INIT_GETRANDOM; INIT___PRINTF_CHK; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc index 00bb2aeef111a4..31ff48cfd2cfcc 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc @@ -2873,6 +2873,18 @@ POST_SYSCALL(rt_sigaction)(long res, long signum, POST_WRITE(oldact, oldact_sz); } } + +PRE_SYSCALL(getrandom)(void *buf, uptr count, long flags) { + if (buf) { + PRE_WRITE(buf, count); + } +} + +POST_SYSCALL(getrandom)(long res, void *buf, uptr count, long flags) { + if (res > 0 && buf) { + POST_WRITE(buf, res); + } +} } // extern "C" #undef PRE_SYSCALL diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 817d24b3492f79..f935119c7bd9a8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -566,4 +566,6 @@ #define SANITIZER_INTERCEPT_GETUSERSHELL (SI_POSIX && !SI_POSIX) #define SANITIZER_INTERCEPT_SL_INIT (SI_FREEBSD || SI_NETBSD) +#define SANITIZER_INTERCEPT_GETRANDOM SI_LINUX + #endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/getrandom.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/getrandom.cpp new file mode 100644 index 00000000000000..08337f537d10f5 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/getrandom.cpp @@ -0,0 +1,22 @@ +// RUN: %clangxx -O2 %s -o %t && %run %t +// UNSUPPORTED: android +// + +#include + +#if !defined(__GLIBC_PREREQ) +#define __GLIBC_PREREQ(a, b) 0 +#endif + +#if __GLIBC_PREREQ(2, 25) +#include +#endif + +int main() { + char buf[16]; + ssize_t n = 1; +#if __GLIBC_PREREQ(2, 25) + n = getrandom(buf, sizeof(buf), 0); +#endif + return (int)(n <= 0); +}