summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2013-10-11 14:13:11 +0000
committerDmitry Vyukov <dvyukov@google.com>2013-10-11 14:13:11 +0000
commit67f5544391c338411b0006bda7dc1b852bbdd4fb (patch)
tree804c0a9557a512eafbe3aad5ea854592401aa0d5 /lib
parent29cec483b760082e264340072f3245fad37e2255 (diff)
downloadcompiler-rt-67f5544391c338411b0006bda7dc1b852bbdd4fb.tar.gz
tsan: catch more races on file descriptors
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@192452 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc17
-rw-r--r--lib/tsan/rtl/tsan_fd.cc2
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc12
3 files changed, 29 insertions, 2 deletions
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index a62ae238d..04c61efdb 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -18,6 +18,7 @@
// COMMON_INTERCEPTOR_INITIALIZE_RANGE
// COMMON_INTERCEPTOR_FD_ACQUIRE
// COMMON_INTERCEPTOR_FD_RELEASE
+// COMMON_INTERCEPTOR_FD_ACCESS
// COMMON_INTERCEPTOR_SET_THREAD_NAME
// COMMON_INTERCEPTOR_ON_EXIT
//===----------------------------------------------------------------------===//
@@ -34,6 +35,10 @@
# define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size)
#endif
+#ifndef COMMON_INTERCEPTOR_FD_ACCESS
+# define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd)
+#endif
+
#if SANITIZER_INTERCEPT_STRCMP
static inline int CharCmpX(unsigned char c1, unsigned char c2) {
return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
@@ -185,6 +190,7 @@ static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
SSIZE_T res = REAL(read)(fd, ptr, count);
if (res > 0)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
@@ -201,6 +207,7 @@ INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
if (res > 0)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
@@ -217,6 +224,7 @@ INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
if (res > 0)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
@@ -234,6 +242,7 @@ INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
int iovcnt) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
if (res > 0) write_iovec(ctx, iov, iovcnt, res);
if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
@@ -249,6 +258,7 @@ INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
OFF_T offset) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
if (res > 0) write_iovec(ctx, iov, iovcnt, res);
if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
@@ -264,6 +274,7 @@ INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
OFF64_T offset) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
if (res > 0) write_iovec(ctx, iov, iovcnt, res);
if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
@@ -278,6 +289,7 @@ INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
if (fd >= 0)
COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
SSIZE_T res = REAL(write)(fd, ptr, count);
@@ -295,6 +307,7 @@ INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
if (fd >= 0)
COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
@@ -312,6 +325,7 @@ INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
OFF64_T offset) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
if (fd >= 0)
COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
@@ -329,6 +343,7 @@ INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
int iovcnt) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
if (res > 0) read_iovec(ctx, iov, iovcnt, res);
@@ -344,6 +359,7 @@ INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
OFF_T offset) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
if (res > 0) read_iovec(ctx, iov, iovcnt, res);
@@ -359,6 +375,7 @@ INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
OFF64_T offset) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
if (res > 0) read_iovec(ctx, iov, iovcnt, res);
diff --git a/lib/tsan/rtl/tsan_fd.cc b/lib/tsan/rtl/tsan_fd.cc
index 332a12d40..703a487a5 100644
--- a/lib/tsan/rtl/tsan_fd.cc
+++ b/lib/tsan/rtl/tsan_fd.cc
@@ -166,6 +166,8 @@ void FdRelease(ThreadState *thr, uptr pc, int fd) {
}
void FdAccess(ThreadState *thr, uptr pc, int fd) {
+ if (fd < 0)
+ return;
DPrintf("#%d: FdAccess(%d)\n", thr->tid, fd);
FdDesc *d = fddesc(thr, pc, fd);
MemoryRead(thr, pc, (uptr)d, kSizeLog8);
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc
index ad7f55914..596664bdf 100644
--- a/lib/tsan/rtl/tsan_interceptors.cc
+++ b/lib/tsan/rtl/tsan_interceptors.cc
@@ -1524,22 +1524,28 @@ TSAN_INTERCEPTOR(int, pipe2, int *pipefd, int flags) {
TSAN_INTERCEPTOR(long_t, send, int fd, void *buf, long_t len, int flags) {
SCOPED_TSAN_INTERCEPTOR(send, fd, buf, len, flags);
- if (fd >= 0)
+ if (fd >= 0) {
+ FdAccess(thr, pc, fd);
FdRelease(thr, pc, fd);
+ }
int res = REAL(send)(fd, buf, len, flags);
return res;
}
TSAN_INTERCEPTOR(long_t, sendmsg, int fd, void *msg, int flags) {
SCOPED_TSAN_INTERCEPTOR(sendmsg, fd, msg, flags);
- if (fd >= 0)
+ if (fd >= 0) {
+ FdAccess(thr, pc, fd);
FdRelease(thr, pc, fd);
+ }
int res = REAL(sendmsg)(fd, msg, flags);
return res;
}
TSAN_INTERCEPTOR(long_t, recv, int fd, void *buf, long_t len, int flags) {
SCOPED_TSAN_INTERCEPTOR(recv, fd, buf, len, flags);
+ if (fd >= 0)
+ FdAccess(thr, pc, fd);
int res = REAL(recv)(fd, buf, len, flags);
if (res >= 0 && fd >= 0) {
FdAcquire(thr, pc, fd);
@@ -1901,6 +1907,8 @@ struct TsanInterceptorContext {
FdAcquire(((TsanInterceptorContext *) ctx)->thr, pc, fd)
#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
FdRelease(((TsanInterceptorContext *) ctx)->thr, pc, fd)
+#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) \
+ FdAccess(((TsanInterceptorContext *) ctx)->thr, pc, fd)
#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
FdSocketAccept(((TsanInterceptorContext *) ctx)->thr, pc, fd, newfd)
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \