[compiler-rt] aa57cab - [msan] Support %ms in scanf.

Evgenii Stepanov via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 6 14:50:21 PDT 2020


Author: Evgenii Stepanov
Date: 2020-08-06T13:54:43-07:00
New Revision: aa57cabae2fc5abc08ab3e17b45f2890fc7c9e42

URL: https://github.com/llvm/llvm-project/commit/aa57cabae2fc5abc08ab3e17b45f2890fc7c9e42
DIFF: https://github.com/llvm/llvm-project/commit/aa57cabae2fc5abc08ab3e17b45f2890fc7c9e42.diff

LOG: [msan] Support %ms in scanf.

Differential Revision: https://reviews.llvm.org/D85350

Added: 
    compiler-rt/test/msan/scanf-allocate.cpp

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc
    compiler-rt/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cpp

Removed: 
    


################################################################################
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 bbbedda8fbe2..082398ba960a 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc
@@ -340,6 +340,12 @@ static void scanf_common(void *ctx, int n_inputs, bool allowGnuMalloc,
       size = 0;
     }
     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, argp, size);
+    // For %ms/%mc, write the allocated output buffer as well.
+    if (dir.allocate) {
+      char *buf = *(char **)argp;
+      if (buf)
+        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);
+    }
   }
 }
 

diff  --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cpp
index 4ed80721c4d1..fa52ccc1994f 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cpp
@@ -48,13 +48,13 @@ static const unsigned P = sizeof(char *);
 
 static void verifyFormatResults(const char *format, unsigned n,
                                 const std::vector<unsigned> &computed_sizes,
-                                va_list expected_sizes) {
-  // "+ 1" because of format string
+                                const std::vector<unsigned> &expected_sizes) {
+  // "+ 1" because of the format string
   ASSERT_EQ(n + 1,
             computed_sizes.size()) << "Unexpected number of format arguments: '"
                                    << format << "'";
   for (unsigned i = 0; i < n; ++i)
-    EXPECT_EQ(va_arg(expected_sizes, unsigned), computed_sizes[i + 1])
+    EXPECT_EQ(expected_sizes[i], computed_sizes[i + 1])
         << "Unexpect write size for argument " << i << ", format string '"
         << format << "'";
 }
@@ -74,8 +74,11 @@ static void testScanf3(void *ctx, int result, bool allowGnuMalloc,
 
 static void testScanf2(const char *format, int scanf_result,
                        bool allowGnuMalloc, unsigned n,
-                       va_list expected_sizes) {
-  std::vector<unsigned> scanf_sizes;
+                       va_list expected_sizes_va) {
+  std::vector<unsigned> scanf_sizes, expected_sizes;
+  for (unsigned i = 0; i < n; ++i)
+    expected_sizes.push_back(va_arg(expected_sizes_va, unsigned));
+
   // 16 args should be enough.
   testScanf3((void *)&scanf_sizes, scanf_result, allowGnuMalloc, format,
              test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
@@ -151,7 +154,6 @@ TEST(SanitizerCommonInterceptors, Scanf) {
   testScanf("%c%d", 2, C, I);
   testScanf("%A%lf", 2, F, D);
 
-  testScanf("%ms %Lf", 2, P, LD);
   testScanf("s%Las", 1, LD);
   testScanf("%ar", 1, F);
 
@@ -202,6 +204,26 @@ TEST(SanitizerCommonInterceptors, Scanf) {
                    test_buf_size);
 }
 
+TEST(SanitizerCommonInterceptors, ScanfAllocate) {
+  const char *buf = "123456";
+
+  // Can not use testScanf() because this case needs a valid pointer to a string
+  // in the scanf argument.
+  {
+    std::vector<unsigned> scanf_sizes;
+    testScanf3((void *)&scanf_sizes, 2, /*allowGnuMalloc=*/false, "%ms", &buf);
+    verifyFormatResults("%ms", 2, scanf_sizes,
+                        {P, (unsigned)(strlen(buf) + 1)});
+  }
+
+  {
+    std::vector<unsigned> scanf_sizes;
+    testScanf3((void *)&scanf_sizes, 2, /*allowGnuMalloc=*/false, "%mc", &buf);
+    verifyFormatResults("%mc", 2, scanf_sizes,
+                        {P, (unsigned)(strlen(buf) + 1)});
+  }
+}
+
 static void testPrintf3(void *ctx, const char *format, ...) {
   va_list ap;
   va_start(ap, format);
@@ -210,8 +232,11 @@ static void testPrintf3(void *ctx, const char *format, ...) {
 }
 
 static void testPrintf2(const char *format, unsigned n,
-                       va_list expected_sizes) {
-  std::vector<unsigned> printf_sizes;
+                        va_list expected_sizes_va) {
+  std::vector<unsigned> printf_sizes, expected_sizes;
+  for (unsigned i = 0; i < n; ++i)
+    expected_sizes.push_back(va_arg(expected_sizes_va, unsigned));
+
   // 16 args should be enough.
   testPrintf3((void *)&printf_sizes, format,
              test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,

diff  --git a/compiler-rt/test/msan/scanf-allocate.cpp b/compiler-rt/test/msan/scanf-allocate.cpp
new file mode 100644
index 000000000000..a525b0c4ab9c
--- /dev/null
+++ b/compiler-rt/test/msan/scanf-allocate.cpp
@@ -0,0 +1,14 @@
+// RUN: %clangxx_msan -O0 %s -o %t && %run %t >%t.out 2>&1
+// FileCheck %s <%t.out
+
+#include <sanitizer/msan_interface.h>
+#include <stdio.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  char *str;
+  sscanf("#string#", "%ms", &str);
+  printf("str = %s\n", str);
+  __msan_check_mem_is_initialized(str, strlen(str) + 1);
+  // CHECK: #string#
+}


        


More information about the llvm-commits mailing list