diff options
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_interceptors_format.inc | 7 | ||||
-rw-r--r-- | lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc | 4 | ||||
-rw-r--r-- | test/asan/TestCases/printf-m.c | 14 |
3 files changed, 21 insertions, 4 deletions
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors_format.inc b/lib/sanitizer_common/sanitizer_common_interceptors_format.inc index 92318cda3..12563499c 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors_format.inc +++ b/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/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc b/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc index 13918aff1..2f0494f82 100644 --- a/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc +++ b/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/test/asan/TestCases/printf-m.c b/test/asan/TestCases/printf-m.c new file mode 100644 index 000000000..1e5ebd92e --- /dev/null +++ b/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; +} |