diff options
author | Lorenzo Martignoni <martignlo@google.com> | 2013-12-04 16:48:09 +0000 |
---|---|---|
committer | Lorenzo Martignoni <martignlo@google.com> | 2013-12-04 16:48:09 +0000 |
commit | dc601d8f3a91678b4ccda465e795c6796b56fd50 (patch) | |
tree | 386647432885ca21f00f7af1e94ef2bbeec91dab /compiler-rt | |
parent | 66037479af2ac686d8d9304129643a95decfb1c0 (diff) | |
download | bcm5719-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.cc | 2 | ||||
-rw-r--r-- | compiler-rt/lib/dfsan/dfsan.h | 5 | ||||
-rw-r--r-- | compiler-rt/lib/dfsan/dfsan_custom.cc | 67 | ||||
-rw-r--r-- | compiler-rt/lib/dfsan/lit_tests/custom.c | 42 |
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() { |