diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-11-28 14:14:48 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-11-28 14:14:48 +0000 |
commit | 9c1f8323ae537bf3a84a6f00ce3b15d99bacc124 (patch) | |
tree | 3afcc2b4048ce2df816e5ddf0c05d6b0dda64512 /compiler-rt | |
parent | 25ecfcf00cc1c06a3c4743b29dc0ea6749adabc1 (diff) | |
download | bcm5719-llvm-9c1f8323ae537bf3a84a6f00ce3b15d99bacc124.tar.gz bcm5719-llvm-9c1f8323ae537bf3a84a6f00ce3b15d99bacc124.zip |
[sanitizer] Intercept iconv.
llvm-svn: 195917
Diffstat (limited to 'compiler-rt')
-rw-r--r-- | compiler-rt/lib/msan/lit_tests/iconv.cc | 48 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc | 26 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_stat.cc | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_stat.h | 1 |
5 files changed, 77 insertions, 0 deletions
diff --git a/compiler-rt/lib/msan/lit_tests/iconv.cc b/compiler-rt/lib/msan/lit_tests/iconv.cc new file mode 100644 index 00000000000..e7c30edd985 --- /dev/null +++ b/compiler-rt/lib/msan/lit_tests/iconv.cc @@ -0,0 +1,48 @@ +// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %t +// RUN: %clangxx_msan -m64 -O0 -g -DPOSITIVE %s -o %t && not %t |& FileCheck %s + +#include <assert.h> +#include <iconv.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> + +int main(void) { + iconv_t cd = iconv_open("ASCII", "ASCII"); + assert(cd != (iconv_t)-1); + + char inbuf_[100]; + strcpy(inbuf_, "sample text"); + char outbuf_[100]; + char *inbuf = inbuf_; + char *outbuf = outbuf_; + size_t inbytesleft = strlen(inbuf_); + size_t outbytesleft = sizeof(outbuf_); + +#ifdef POSITIVE + { + char u; + char *volatile p = &u; + inbuf_[5] = *p; + } +#endif + + size_t res; + res = iconv(cd, 0, 0, 0, 0); + assert(res != (size_t)-1); + + res = iconv(cd, 0, 0, &outbuf, &outbytesleft); + assert(res != (size_t)-1); + + res = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + // CHECK: MemorySanitizer: use-of-uninitialized-value + // CHECK: #0 {{.*}} in main {{.*}}iconv.cc:[[@LINE-2]] + assert(res != (size_t)-1); + assert(inbytesleft == 0); + + assert(memcmp(inbuf_, outbuf_, strlen(inbuf_)) == 0); + + iconv_close(cd); + return 0; +} diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 1668bb0fa84..61bc06cf513 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2853,6 +2853,31 @@ INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim, #define INIT_GETLINE #endif +#if SANITIZER_INTERCEPT_ICONV +INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft, + char **outbuf, SIZE_T *outbytesleft) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf, + outbytesleft); + if (inbytesleft) + COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft)); + if (inbuf && inbytesleft) + COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft); + if (outbytesleft) + COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft)); + void *outbuf_orig = outbuf ? *outbuf : 0; + SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft); + if (res != (SIZE_T) - 1 && outbuf && *outbuf > outbuf_orig) { + SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig; + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz); + } + return res; +} +#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv); +#else +#define INIT_ICONV +#endif + #define SANITIZER_COMMON_INTERCEPTORS_INIT \ INIT_STRCMP; \ INIT_STRNCMP; \ @@ -2963,4 +2988,5 @@ INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim, INIT_LGAMMA_R; \ INIT_DRAND48_R; \ INIT_GETLINE; \ + INIT_ICONV; \ /**/ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index e79b8c83e13..0db69021d22 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -158,6 +158,7 @@ # define SANITIZER_INTERCEPT_LGAMMA SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_LGAMMA_R SI_LINUX # define SANITIZER_INTERCEPT_DRAND48_R SI_LINUX_NOT_ANDROID +# define SANITIZER_INTERCEPT_ICONV SI_MAC || SI_LINUX_NOT_ANDROID // FIXME: getline seems to be available on OSX 10.7 # define SANITIZER_INTERCEPT_GETLINE SI_LINUX_NOT_ANDROID diff --git a/compiler-rt/lib/tsan/rtl/tsan_stat.cc b/compiler-rt/lib/tsan/rtl/tsan_stat.cc index dcf28c8d49b..256ae835a11 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_stat.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_stat.cc @@ -416,6 +416,7 @@ void StatOutput(u64 *stat) { name[StatInt_lrand48_r] = " lrand48_r "; name[StatInt_getline] = " getline "; name[StatInt_getdelim] = " getdelim "; + name[StatInt_iconv] = " iconv "; name[StatInt_pthread_attr_getdetachstate] = " pthread_addr_getdetachstate "; // NOLINT name[StatInt_pthread_attr_getguardsize] = " pthread_addr_getguardsize "; // NOLINT diff --git a/compiler-rt/lib/tsan/rtl/tsan_stat.h b/compiler-rt/lib/tsan/rtl/tsan_stat.h index 1869c9d1fd8..afb3c22d6d5 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_stat.h +++ b/compiler-rt/lib/tsan/rtl/tsan_stat.h @@ -411,6 +411,7 @@ enum StatType { StatInt_lrand48_r, StatInt_getline, StatInt_getdelim, + StatInt_iconv, StatInt_pthread_attr_getdetachstate, StatInt_pthread_attr_getguardsize, |