Skip to content

Commit

Permalink
[tsan] Fix the open and open64 interceptors to have correct declarati…
Browse files Browse the repository at this point in the history
…ons (variadic functions)

Not matching the (real) variadic declaration makes the interceptor take garbage inputs on Darwin/AArch64.

Differential Revision: https://reviews.llvm.org/D84570
  • Loading branch information
kubamracek committed Jul 30, 2020
1 parent 0a00a7d commit 1260a15
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
23 changes: 17 additions & 6 deletions compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
Expand Up @@ -31,6 +31,8 @@
#include "tsan_mman.h"
#include "tsan_fd.h"

#include <stdarg.h>

using namespace __tsan;

#if SANITIZER_FREEBSD || SANITIZER_MAC
Expand Down Expand Up @@ -135,6 +137,7 @@ const int PTHREAD_BARRIER_SERIAL_THREAD = -1;
#endif
const int MAP_FIXED = 0x10;
typedef long long_t;
typedef __sanitizer::u16 mode_t;

// From /usr/include/unistd.h
# define F_ULOCK 0 /* Unlock a previously locked region. */
Expand Down Expand Up @@ -1508,20 +1511,28 @@ TSAN_INTERCEPTOR(int, fstat64, int fd, void *buf) {
#define TSAN_MAYBE_INTERCEPT_FSTAT64
#endif

TSAN_INTERCEPTOR(int, open, const char *name, int flags, int mode) {
SCOPED_TSAN_INTERCEPTOR(open, name, flags, mode);
TSAN_INTERCEPTOR(int, open, const char *name, int oflag, ...) {
va_list ap;
va_start(ap, oflag);
mode_t mode = va_arg(ap, int);
va_end(ap);
SCOPED_TSAN_INTERCEPTOR(open, name, oflag, mode);
READ_STRING(thr, pc, name, 0);
int fd = REAL(open)(name, flags, mode);
int fd = REAL(open)(name, oflag, mode);
if (fd >= 0)
FdFileCreate(thr, pc, fd);
return fd;
}

#if SANITIZER_LINUX
TSAN_INTERCEPTOR(int, open64, const char *name, int flags, int mode) {
SCOPED_TSAN_INTERCEPTOR(open64, name, flags, mode);
TSAN_INTERCEPTOR(int, open64, const char *name, int oflag, ...) {
va_list ap;
va_start(ap, oflag);
mode_t mode = va_arg(ap, int);
va_end(ap);
SCOPED_TSAN_INTERCEPTOR(open64, name, oflag, mode);
READ_STRING(thr, pc, name, 0);
int fd = REAL(open64)(name, flags, mode);
int fd = REAL(open64)(name, oflag, mode);
if (fd >= 0)
FdFileCreate(thr, pc, fd);
return fd;
Expand Down
24 changes: 24 additions & 0 deletions compiler-rt/test/tsan/variadic-open.cpp
@@ -0,0 +1,24 @@
// RUN: %clangxx_tsan -O1 %s -o %t && %run %t %t.tmp 2>&1 | FileCheck %s
#include <stdio.h>
#include <assert.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

int main(int argc, char *argv[]) {
fprintf(stderr, "Hello world.\n");
assert(argv[1]);
unlink(argv[1]);
int fd = open(argv[1], O_RDWR | O_CREAT, 0600);
assert(fd != -1);
struct stat info;
int result = fstat(fd, &info);
fprintf(stderr, "permissions = 0%o\n", info.st_mode & ~S_IFMT);
assert(result == 0);
close(fd);
fprintf(stderr, "Done.\n");
}

// CHECK: Hello world.
// CHECK: permissions = 0600
// CHECK: Done.

0 comments on commit 1260a15

Please sign in to comment.