[compiler-rt] r250113 - [asan] Zero initialize sem_t in sem_init.
Evgeniy Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 12 14:32:30 PDT 2015
Author: eugenis
Date: Mon Oct 12 16:32:30 2015
New Revision: 250113
URL: http://llvm.org/viewvc/llvm-project?rev=250113&view=rev
Log:
[asan] Zero initialize sem_t in sem_init.
Old version of sem_init (GLIBC_2.0) fails to initialize parts of
sem_t that are used in sem_timedwait. This is fixed in GLIBC_2.1,
but since ASan interceptors downgrade sem_* to the oldest available
version, this can introduce bugs that are only present in sanitized
build. Workaround by zero-initializing sem_t in sem_init.
Added:
compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h
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=250113&r1=250112&r2=250113&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Mon Oct 12 16:32:30 2015
@@ -5114,21 +5114,26 @@ INTERCEPTOR(__sanitizer_FILE *, fopencoo
#endif // SANITIZER_INTERCEPT_FOPENCOOKIE
#if SANITIZER_INTERCEPT_SEM
-INTERCEPTOR(int, sem_init, void *s, int pshared, unsigned value) {
+INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);
+ // Workaround a bug in glibc's "old" semaphore implementation by
+ // zero-initializing the sem_t contents. This has to be done here because
+ // interceptors bind to the lowest symbols version by default, hitting the
+ // buggy code path while the non-sanitized build of the same code works fine.
+ REAL(memset)(s, 0, sizeof(*s));
int res = REAL(sem_init)(s, pshared, value);
return res;
}
-INTERCEPTOR(int, sem_destroy, void *s) {
+INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);
int res = REAL(sem_destroy)(s);
return res;
}
-INTERCEPTOR(int, sem_wait, void *s) {
+INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);
int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);
@@ -5138,7 +5143,7 @@ INTERCEPTOR(int, sem_wait, void *s) {
return res;
}
-INTERCEPTOR(int, sem_trywait, void *s) {
+INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);
int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s);
@@ -5148,7 +5153,7 @@ INTERCEPTOR(int, sem_trywait, void *s) {
return res;
}
-INTERCEPTOR(int, sem_timedwait, void *s, void *abstime) {
+INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);
COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);
@@ -5159,7 +5164,7 @@ INTERCEPTOR(int, sem_timedwait, void *s,
return res;
}
-INTERCEPTOR(int, sem_post, void *s) {
+INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);
COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);
@@ -5167,7 +5172,7 @@ INTERCEPTOR(int, sem_post, void *s) {
return res;
}
-INTERCEPTOR(int, sem_getvalue, void *s, int *sval) {
+INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);
int res = REAL(sem_getvalue)(s, sval);
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc?rev=250113&r1=250112&r2=250113&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc Mon Oct 12 16:32:30 2015
@@ -122,6 +122,7 @@
# if defined(__mips64) || defined(__aarch64__)
# include <asm/ptrace.h>
# endif
+# include <semaphore.h>
#endif
#if !SANITIZER_ANDROID
@@ -1241,4 +1242,8 @@ CHECK_SIZE_AND_OFFSET(cookie_io_function
CHECK_SIZE_AND_OFFSET(cookie_io_functions_t, close);
#endif
+#if SANITIZER_LINUX || SANITIZER_FREEBSD
+CHECK_TYPE_SIZE(sem_t);
+#endif
+
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h?rev=250113&r1=250112&r2=250113&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h Mon Oct 12 16:32:30 2015
@@ -150,6 +150,18 @@ namespace __sanitizer {
};
const unsigned old_sigset_t_sz = sizeof(unsigned long);
+
+ struct __sanitizer_sem_t {
+#if SANITIZER_ANDROID && defined(_LP64)
+ int data[4];
+#elif SANITIZER_ANDROID && !defined(_LP64)
+ int data;
+#elif SANITIZER_LINUX
+ uptr data[4];
+#elif SANITIZER_FREEBSD
+ u32 data[4];
+#endif
+ };
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD
#if SANITIZER_ANDROID
Added: compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc?rev=250113&view=auto
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc (added)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc Mon Oct 12 16:32:30 2015
@@ -0,0 +1,32 @@
+// RUN: %clangxx -O0 -g %s -lutil -o %t && %run %t
+// This test depends on the glibc layout of struct sem_t and checks that we
+// don't leave sem_t::private uninitialized.
+// UNSUPPORTED: android
+#include <assert.h>
+#include <semaphore.h>
+#include <string.h>
+
+void my_sem_init(bool priv, int value, unsigned *a, unsigned char *b) {
+ sem_t sem;
+ memset(&sem, 0xAB, sizeof(sem));
+ sem_init(&sem, priv, value);
+
+ char *p = (char *)&sem;
+ memcpy(a, p, sizeof(unsigned));
+ memcpy(b, p + sizeof(unsigned), sizeof(char));
+
+ sem_destroy(&sem);
+}
+
+int main() {
+ unsigned a;
+ unsigned char b;
+
+ my_sem_init(false, 42, &a, &b);
+ assert(a == 42);
+ assert(b != 0xAB);
+
+ my_sem_init(true, 43, &a, &b);
+ assert(a == 43);
+ assert(b != 0xAB);
+}
More information about the llvm-commits
mailing list