summaryrefslogtreecommitdiffstats
path: root/compiler-rt
diff options
context:
space:
mode:
authorLorenzo Martignoni <martignlo@google.com>2013-12-04 16:48:09 +0000
committerLorenzo Martignoni <martignlo@google.com>2013-12-04 16:48:09 +0000
commitdc601d8f3a91678b4ccda465e795c6796b56fd50 (patch)
tree386647432885ca21f00f7af1e94ef2bbeec91dab /compiler-rt
parent66037479af2ac686d8d9304129643a95decfb1c0 (diff)
downloadbcm5719-llvm-dc601d8f3a91678b4ccda465e795c6796b56fd50.tar.gz
bcm5719-llvm-dc601d8f3a91678b4ccda465e795c6796b56fd50.zip
[DFSan] Change the way labels are propagated when comparing memory through libc functions.
Differential Revision: http://llvm-reviews.chandlerc.com/D2252 llvm-svn: 196388
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/lib/dfsan/dfsan.cc2
-rw-r--r--compiler-rt/lib/dfsan/dfsan.h5
-rw-r--r--compiler-rt/lib/dfsan/dfsan_custom.cc67
-rw-r--r--compiler-rt/lib/dfsan/lit_tests/custom.c42
4 files changed, 97 insertions, 19 deletions
diff --git a/compiler-rt/lib/dfsan/dfsan.cc b/compiler-rt/lib/dfsan/dfsan.cc
index 72d05c68604..f4f726a34c6 100644
--- a/compiler-rt/lib/dfsan/dfsan.cc
+++ b/compiler-rt/lib/dfsan/dfsan.cc
@@ -233,9 +233,11 @@ dfsan_has_label_with_desc(dfsan_label label, const char *desc) {
static void InitializeFlags(Flags &f, const char *env) {
f.warn_unimplemented = true;
f.warn_nonzero_labels = false;
+ f.strict_data_dependencies = true;
ParseFlag(env, &f.warn_unimplemented, "warn_unimplemented");
ParseFlag(env, &f.warn_nonzero_labels, "warn_nonzero_labels");
+ ParseFlag(env, &f.strict_data_dependencies, "strict_data_dependencies");
}
#ifdef DFSAN_NOLIBC
diff --git a/compiler-rt/lib/dfsan/dfsan.h b/compiler-rt/lib/dfsan/dfsan.h
index 693e0c5efe0..92a1357d7c5 100644
--- a/compiler-rt/lib/dfsan/dfsan.h
+++ b/compiler-rt/lib/dfsan/dfsan.h
@@ -55,6 +55,11 @@ struct Flags {
bool warn_unimplemented;
// Whether to warn on non-zero labels.
bool warn_nonzero_labels;
+ // Whether to propagate labels only when there is an obvious data dependency
+ // (e.g., when comparing strings, ignore the fact that the output of the
+ // comparison might be data-dependent on the content of the strings). This
+ // applies only to the custom functions defined in 'custom.c'.
+ bool strict_data_dependencies;
};
extern Flags flags_data;
diff --git a/compiler-rt/lib/dfsan/dfsan_custom.cc b/compiler-rt/lib/dfsan/dfsan_custom.cc
index b654d2f1502..0178a6e25c2 100644
--- a/compiler-rt/lib/dfsan/dfsan_custom.cc
+++ b/compiler-rt/lib/dfsan/dfsan_custom.cc
@@ -67,7 +67,11 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strchr(const char *s, int c,
dfsan_label *ret_label) {
for (size_t i = 0;; ++i) {
if (s[i] == c || s[i] == 0) {
- *ret_label = dfsan_union(dfsan_read_label(s, i+1), c_label);
+ if (flags().strict_data_dependencies) {
+ *ret_label = s_label;
+ } else {
+ *ret_label = dfsan_union(dfsan_read_label(s, i + 1), c_label);
+ }
return s[i] == 0 ? 0 : const_cast<char *>(s+i);
}
}
@@ -81,13 +85,22 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2,
const char *cs1 = (const char *) s1, *cs2 = (const char *) s2;
for (size_t i = 0; i != n; ++i) {
if (cs1[i] != cs2[i]) {
- *ret_label = dfsan_union(dfsan_read_label(cs1, i+1),
- dfsan_read_label(cs2, i+1));
+ if (flags().strict_data_dependencies) {
+ *ret_label = 0;
+ } else {
+ *ret_label = dfsan_union(dfsan_read_label(cs1, i + 1),
+ dfsan_read_label(cs2, i + 1));
+ }
return cs1[i] - cs2[i];
}
}
- *ret_label = dfsan_union(dfsan_read_label(cs1, n),
- dfsan_read_label(cs2, n));
+
+ if (flags().strict_data_dependencies) {
+ *ret_label = 0;
+ } else {
+ *ret_label = dfsan_union(dfsan_read_label(cs1, n),
+ dfsan_read_label(cs2, n));
+ }
return 0;
}
@@ -97,8 +110,12 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcmp(const char *s1, const char *s2,
dfsan_label *ret_label) {
for (size_t i = 0;; ++i) {
if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0) {
- *ret_label = dfsan_union(dfsan_read_label(s1, i+1),
- dfsan_read_label(s2, i+1));
+ if (flags().strict_data_dependencies) {
+ *ret_label = 0;
+ } else {
+ *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
+ dfsan_read_label(s2, i + 1));
+ }
return s1[i] - s2[i];
}
}
@@ -110,8 +127,12 @@ __dfsw_strcasecmp(const char *s1, const char *s2, dfsan_label s1_label,
dfsan_label s2_label, dfsan_label *ret_label) {
for (size_t i = 0;; ++i) {
if (tolower(s1[i]) != tolower(s2[i]) || s1[i] == 0 || s2[i] == 0) {
- *ret_label = dfsan_union(dfsan_read_label(s1, i+1),
- dfsan_read_label(s2, i+1));
+ if (flags().strict_data_dependencies) {
+ *ret_label = 0;
+ } else {
+ *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
+ dfsan_read_label(s2, i + 1));
+ }
return s1[i] - s2[i];
}
}
@@ -129,9 +150,13 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2,
}
for (size_t i = 0;; ++i) {
- if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || i == n-1) {
- *ret_label = dfsan_union(dfsan_read_label(s1, i+1),
- dfsan_read_label(s2, i+1));
+ if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || i == n - 1) {
+ if (flags().strict_data_dependencies) {
+ *ret_label = 0;
+ } else {
+ *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
+ dfsan_read_label(s2, i + 1));
+ }
return s1[i] - s2[i];
}
}
@@ -150,8 +175,12 @@ __dfsw_strncasecmp(const char *s1, const char *s2, size_t n,
for (size_t i = 0;; ++i) {
if (tolower(s1[i]) != tolower(s2[i]) || s1[i] == 0 || s2[i] == 0 ||
i == n - 1) {
- *ret_label = dfsan_union(dfsan_read_label(s1, i+1),
- dfsan_read_label(s2, i+1));
+ if (flags().strict_data_dependencies) {
+ *ret_label = 0;
+ } else {
+ *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
+ dfsan_read_label(s2, i + 1));
+ }
return s1[i] - s2[i];
}
}
@@ -171,7 +200,11 @@ SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_calloc(size_t nmemb, size_t size,
SANITIZER_INTERFACE_ATTRIBUTE size_t
__dfsw_strlen(const char *s, dfsan_label s_label, dfsan_label *ret_label) {
size_t ret = strlen(s);
- *ret_label = dfsan_read_label(s, ret+1);
+ if (flags().strict_data_dependencies) {
+ *ret_label = 0;
+ } else {
+ *ret_label = dfsan_read_label(s, ret + 1);
+ }
return ret;
}
@@ -191,7 +224,7 @@ SANITIZER_INTERFACE_ATTRIBUTE
void *__dfsw_memcpy(void *dest, const void *src, size_t n,
dfsan_label dest_label, dfsan_label src_label,
dfsan_label n_label, dfsan_label *ret_label) {
- *ret_label = 0;
+ *ret_label = dest_label;
return dfsan_memcpy(dest, src, n);
}
@@ -200,7 +233,7 @@ void *__dfsw_memset(void *s, int c, size_t n,
dfsan_label s_label, dfsan_label c_label,
dfsan_label n_label, dfsan_label *ret_label) {
dfsan_memset(s, c, c_label, n);
- *ret_label = 0;
+ *ret_label = s_label;
return s;
}
diff --git a/compiler-rt/lib/dfsan/lit_tests/custom.c b/compiler-rt/lib/dfsan/lit_tests/custom.c
index dd6d580a056..b4002337030 100644
--- a/compiler-rt/lib/dfsan/lit_tests/custom.c
+++ b/compiler-rt/lib/dfsan/lit_tests/custom.c
@@ -1,5 +1,7 @@
-// RUN: %clang_dfsan -m64 %s -o %t && %t
-// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t && %t
+// RUN: %clang_dfsan -m64 %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %t
+// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %t
+// RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES -m64 %s -o %t && %t
+// RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES -mllvm -dfsan-args-abi -m64 %s -o %t && %t
// Tests custom implementations of various glibc functions.
@@ -75,7 +77,11 @@ void test_memcmp() {
int rv = memcmp(str1, str2, sizeof(str1));
assert(rv < 0);
+#ifdef STRICT_DATA_DEPENDENCIES
+ ASSERT_ZERO_LABEL(rv);
+#else
ASSERT_LABEL(rv, i_j_label);
+#endif
}
void test_memcpy() {
@@ -108,7 +114,11 @@ void test_strcmp() {
int rv = strcmp(str1, str2);
assert(rv < 0);
+#ifdef STRICT_DATA_DEPENDENCIES
+ ASSERT_ZERO_LABEL(rv);
+#else
ASSERT_LABEL(rv, i_j_label);
+#endif
}
void test_strlen() {
@@ -117,7 +127,11 @@ void test_strlen() {
int rv = strlen(str1);
assert(rv == 4);
+#ifdef STRICT_DATA_DEPENDENCIES
+ ASSERT_ZERO_LABEL(rv);
+#else
ASSERT_LABEL(rv, i_label);
+#endif
}
void test_strdup() {
@@ -160,7 +174,11 @@ void test_strncmp() {
int rv = strncmp(str1, str2, sizeof(str1));
assert(rv < 0);
+#ifdef STRICT_DATA_DEPENDENCIES
+ ASSERT_ZERO_LABEL(rv);
+#else
ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
+#endif
rv = strncmp(str1, str2, 3);
assert(rv == 0);
@@ -175,11 +193,19 @@ void test_strcasecmp() {
int rv = strcasecmp(str1, str2);
assert(rv < 0);
+#ifdef STRICT_DATA_DEPENDENCIES
+ ASSERT_ZERO_LABEL(rv);
+#else
ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
+#endif
rv = strcasecmp(str1, str3);
assert(rv == 0);
+#ifdef STRICT_DATA_DEPENDENCIES
+ ASSERT_ZERO_LABEL(rv);
+#else
ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
+#endif
}
void test_strncasecmp() {
@@ -189,7 +215,11 @@ void test_strncasecmp() {
int rv = strncasecmp(str1, str2, sizeof(str1));
assert(rv < 0);
+#ifdef STRICT_DATA_DEPENDENCIES
+ ASSERT_ZERO_LABEL(rv);
+#else
ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
+#endif
rv = strncasecmp(str1, str2, 3);
assert(rv == 0);
@@ -206,11 +236,19 @@ void test_strchr() {
crv = strchr(str1, '1');
assert(crv == &str1[3]);
+#ifdef STRICT_DATA_DEPENDENCIES
+ ASSERT_ZERO_LABEL(crv);
+#else
ASSERT_LABEL(crv, i_label);
+#endif
crv = strchr(str1, 'x');
assert(!crv);
+#ifdef STRICT_DATA_DEPENDENCIES
+ ASSERT_ZERO_LABEL(crv);
+#else
ASSERT_LABEL(crv, i_label);
+#endif
}
void test_calloc() {
OpenPOWER on IntegriCloud