Skip to content

Commit

Permalink
[compiler-rt] Implement getrandom interception
Browse files Browse the repository at this point in the history
Summary:
Straightforward implementation of `getrandom` syscall and libc
hooks.

Test Plan: Local MSAN failures caused by uninstrumented `getrandom`
calls stop failing.

Patch by Andrew Krieger.

Reviewers: eugenis, vitalybuka

Reviewed By: vitalybuka

Subscribers: srhines, kubamracek, dberris, #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D65551

llvm-svn: 367999
  • Loading branch information
vitalybuka committed Aug 6, 2019
1 parent dba4dd1 commit ac9ee01
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 0 deletions.
16 changes: 16 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -9848,6 +9863,7 @@ static void InitializeCommonInterceptors() {
INIT_FDEVNAME;
INIT_GETUSERSHELL;
INIT_SL_INIT;
INIT_GETRANDOM;

INIT___PRINTF_CHK;
}
12 changes: 12 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
22 changes: 22 additions & 0 deletions compiler-rt/test/sanitizer_common/TestCases/Linux/getrandom.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// RUN: %clangxx -O2 %s -o %t && %run %t
// UNSUPPORTED: android
//

#include <sys/types.h>

#if !defined(__GLIBC_PREREQ)
#define __GLIBC_PREREQ(a, b) 0
#endif

#if __GLIBC_PREREQ(2, 25)
#include <sys/random.h>
#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);
}

0 comments on commit ac9ee01

Please sign in to comment.