[tsan] Fix the open and open64 interceptors to have correct declarations (variadic functions)

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

Differential Revision: https://reviews.llvm.org/D84570
This commit is contained in:
Kuba Mracek 2020-07-30 09:00:14 -07:00
parent 0a00a7d577
commit 1260a155c3
2 changed files with 41 additions and 6 deletions

View File

@ -31,6 +31,8 @@
#include "tsan_mman.h" #include "tsan_mman.h"
#include "tsan_fd.h" #include "tsan_fd.h"
#include <stdarg.h>
using namespace __tsan; using namespace __tsan;
#if SANITIZER_FREEBSD || SANITIZER_MAC #if SANITIZER_FREEBSD || SANITIZER_MAC
@ -135,6 +137,7 @@ const int PTHREAD_BARRIER_SERIAL_THREAD = -1;
#endif #endif
const int MAP_FIXED = 0x10; const int MAP_FIXED = 0x10;
typedef long long_t; typedef long long_t;
typedef __sanitizer::u16 mode_t;
// From /usr/include/unistd.h // From /usr/include/unistd.h
# define F_ULOCK 0 /* Unlock a previously locked region. */ # define F_ULOCK 0 /* Unlock a previously locked region. */
@ -1508,20 +1511,28 @@ TSAN_INTERCEPTOR(int, fstat64, int fd, void *buf) {
#define TSAN_MAYBE_INTERCEPT_FSTAT64 #define TSAN_MAYBE_INTERCEPT_FSTAT64
#endif #endif
TSAN_INTERCEPTOR(int, open, const char *name, int flags, int mode) { TSAN_INTERCEPTOR(int, open, const char *name, int oflag, ...) {
SCOPED_TSAN_INTERCEPTOR(open, name, flags, mode); 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); READ_STRING(thr, pc, name, 0);
int fd = REAL(open)(name, flags, mode); int fd = REAL(open)(name, oflag, mode);
if (fd >= 0) if (fd >= 0)
FdFileCreate(thr, pc, fd); FdFileCreate(thr, pc, fd);
return fd; return fd;
} }
#if SANITIZER_LINUX #if SANITIZER_LINUX
TSAN_INTERCEPTOR(int, open64, const char *name, int flags, int mode) { TSAN_INTERCEPTOR(int, open64, const char *name, int oflag, ...) {
SCOPED_TSAN_INTERCEPTOR(open64, name, flags, mode); 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); READ_STRING(thr, pc, name, 0);
int fd = REAL(open64)(name, flags, mode); int fd = REAL(open64)(name, oflag, mode);
if (fd >= 0) if (fd >= 0)
FdFileCreate(thr, pc, fd); FdFileCreate(thr, pc, fd);
return fd; return fd;

View File

@ -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.