diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-09-09 08:58:54 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-09-09 08:58:54 +0000 |
commit | cf02f171a98e706ffa3a7deb45a03fcb622106d3 (patch) | |
tree | 44e5d730937eb46cd29eb8971c9a0ada4108b4d8 /compiler-rt | |
parent | a4a59d7468d4fbecca0d4945ed7fd09ec707d387 (diff) | |
download | bcm5719-llvm-cf02f171a98e706ffa3a7deb45a03fcb622106d3.tar.gz bcm5719-llvm-cf02f171a98e706ffa3a7deb45a03fcb622106d3.zip |
[sanitizer] Fix PR17138.
strerror_r on OSX returns a positive error code when the errno value is
unknown. Buffer contents are initialized in any case.
llvm-svn: 190295
Diffstat (limited to 'compiler-rt')
-rw-r--r-- | compiler-rt/lib/asan/lit_tests/TestCases/strerror_r_test.cc | 13 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc | 6 |
2 files changed, 17 insertions, 2 deletions
diff --git a/compiler-rt/lib/asan/lit_tests/TestCases/strerror_r_test.cc b/compiler-rt/lib/asan/lit_tests/TestCases/strerror_r_test.cc new file mode 100644 index 00000000000..0df009b83f9 --- /dev/null +++ b/compiler-rt/lib/asan/lit_tests/TestCases/strerror_r_test.cc @@ -0,0 +1,13 @@ +// RUN: %clangxx_asan -O0 %s -o %t && %t + +// Regression test for PR17138. + +#include <assert.h> +#include <string.h> + +int main() { + char buf[1024]; + char *res = (char *)strerror_r(300, buf, sizeof(buf)); + assert(res != 0); + 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 49982584edc..0322f2bd531 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -1807,12 +1807,14 @@ INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { // writes message to buf. // * GNU version returns message pointer, which points to either buf or some // static storage. - if (!res) { + SIZE_T posix_res = (SIZE_T)res; + if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) { // POSIX version. Spec is not clear on whether buf is NULL-terminated. + // At least on OSX, buf contents are valid even when the call fails. SIZE_T sz = internal_strnlen(buf, buflen); if (sz < buflen) ++sz; COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); - } else if ((SIZE_T)res < (SIZE_T) - 1024) { + } else { // GNU version. COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); } |