[compiler-rt] r304858 - [tsan]: Fix GNU version of strerror_r interceptor
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 6 18:53:39 PDT 2017
Author: vitalybuka
Date: Tue Jun 6 20:53:38 2017
New Revision: 304858
URL: http://llvm.org/viewvc/llvm-project?rev=304858&view=rev
Log:
[tsan]: Fix GNU version of strerror_r interceptor
GNU version of strerror_r returns a result pointer that doesn't match the input
buffer. The result pointer is in fact a pointer to some internal storage.
TSAN was recording a write to this location, which was incorrect.
Fixed https://github.com/google/sanitizers/issues/696
Added:
compiler-rt/trunk/test/msan/Linux/strerror_r.cc
compiler-rt/trunk/test/tsan/strerror_r.cc
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=304858&r1=304857&r2=304858&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Tue Jun 6 20:53:38 2017
@@ -3395,7 +3395,10 @@ INTERCEPTOR(char *, strerror_r, int errn
// its metadata. See
// https://github.com/google/sanitizers/issues/321.
char *res = REAL(strerror_r)(errnum, buf, buflen);
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+ if (res == buf)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+ else
+ COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
return res;
}
#endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE ||
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc?rev=304858&r1=304857&r2=304858&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc Tue Jun 6 20:53:38 2017
@@ -345,6 +345,7 @@ void MemoryAccessRange(ThreadState *thr,
StatInc(thr, StatMopRange);
if (*shadow_mem == kShadowRodata) {
+ DCHECK(!is_write);
// Access to .rodata section, no races here.
// Measurements show that it can be 10-20% of all memory accesses.
StatInc(thr, StatMopRangeRodata);
Added: compiler-rt/trunk/test/msan/Linux/strerror_r.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/Linux/strerror_r.cc?rev=304858&view=auto
==============================================================================
--- compiler-rt/trunk/test/msan/Linux/strerror_r.cc (added)
+++ compiler-rt/trunk/test/msan/Linux/strerror_r.cc Tue Jun 6 20:53:38 2017
@@ -0,0 +1,18 @@
+// RUN: %clang_msan -O0 -g %s -o %t && %run %t
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+int main() {
+ char buf[1000];
+ char *res = strerror_r(EINVAL, buf, sizeof(buf));
+ assert(res);
+ volatile int z = strlen(res);
+
+ res = strerror_r(-1, buf, sizeof(buf));
+ assert(res);
+ z = strlen(res);
+
+ return 0;
+}
Added: compiler-rt/trunk/test/tsan/strerror_r.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/strerror_r.cc?rev=304858&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/strerror_r.cc (added)
+++ compiler-rt/trunk/test/tsan/strerror_r.cc Tue Jun 6 20:53:38 2017
@@ -0,0 +1,28 @@
+// RUN: %clangxx_tsan -O1 -DTEST_ERROR=ERANGE %s -o %t && %run %t 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-SYS %s
+// RUN: %clangxx_tsan -O1 -DTEST_ERROR=-1 %s -o %t && not %run %t 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-USER %s
+
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+
+char buffer[1000];
+
+void *Thread(void *p) {
+ return strerror_r(TEST_ERROR, buffer, sizeof(buffer));
+}
+
+int main() {
+ pthread_t th[2];
+ pthread_create(&th[0], 0, Thread, 0);
+ pthread_create(&th[1], 0, Thread, 0);
+ pthread_join(th[0], 0);
+ pthread_join(th[1], 0);
+ fprintf(stderr, "DONE\n");
+}
+
+// CHECK-USER: WARNING: ThreadSanitizer: data race
+// CHECK-SYS-NOT: WARNING: ThreadSanitizer: data race
+
+// CHECK: DONE
More information about the llvm-commits
mailing list