summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors_format.inc7
-rw-r--r--lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc4
-rw-r--r--test/asan/TestCases/printf-m.c14
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;
+}