diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-12-27 22:14:03 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-12-27 22:14:03 +0000 |
commit | f787cf7ee65018d99a9da6676e76079a97847bf8 (patch) | |
tree | facf178b80023dbfe454ef057d9a4be035cc86f0 | |
parent | deeca6de08ff517ecc4db90598d67e23c930302f (diff) | |
download | bcm5719-llvm-f787cf7ee65018d99a9da6676e76079a97847bf8.tar.gz bcm5719-llvm-f787cf7ee65018d99a9da6676e76079a97847bf8.zip |
[asan] Fix handling of %m in printf interceptor.
llvm-svn: 290632
3 files changed, 21 insertions, 4 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc index 92318cda35f..12563499c51 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc @@ -435,10 +435,6 @@ static const char *printf_parse_next(const char *p, PrintfDirective *dir) { } static int printf_get_value_size(PrintfDirective *dir) { - if (dir->convSpecifier == 'm') { - return sizeof(char *); - } - if (char_is_one_of(dir->convSpecifier, "cCsS")) { unsigned charSize = format_get_char_size(dir->convSpecifier, dir->lengthModifier); @@ -519,6 +515,9 @@ static void printf_common(void *ctx, const char *format, va_list aq) { // Dynamic precision SKIP_SCALAR_ARG(&aq, 'd', sizeof(int)); } + // %m does not require an argument: strlen(errno). + if (dir.convSpecifier == 'm') + continue; int size = printf_get_value_size(&dir); if (size == FSS_INVALID) { Report("WARNING: unexpected format specifier in printf " diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc index 13918aff100..2f0494f82b0 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc @@ -256,4 +256,8 @@ TEST(SanitizerCommonInterceptors, Printf) { // Checks for wide-character strings are not implemented yet. testPrintf("%ls", 1, 0); + + testPrintf("%m", 0); + testPrintf("%m%s", 1, test_buf_size); + testPrintf("%s%m%s", 2, test_buf_size, test_buf_size); } diff --git a/compiler-rt/test/asan/TestCases/printf-m.c b/compiler-rt/test/asan/TestCases/printf-m.c new file mode 100644 index 00000000000..1e5ebd92e3e --- /dev/null +++ b/compiler-rt/test/asan/TestCases/printf-m.c @@ -0,0 +1,14 @@ +// RUN: %clang_asan -O2 %s -o %t && %run %t + +// FIXME: printf is not intercepted on Windows yet. +// XFAIL: win32 + +#include <stdio.h> + +int main() { + char s[5] = {'w', 'o', 'r', 'l', 'd'}; + // Test that %m does not consume an argument. If it does, %s would apply to + // the 5-character buffer, resulting in a stack-buffer-overflow report. + printf("%m %s, %.5s\n", "hello", s); + return 0; +} |