[compiler-rt] beeb37a - [sanitizer] scanf interceptor: fix write size for %mc/%mC/%mS
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 27 22:19:36 PDT 2023
Author: Fangrui Song
Date: 2023-08-27T22:19:31-07:00
New Revision: beeb37a8f3275281be305d2d1afe35ca053e21c0
URL: https://github.com/llvm/llvm-project/commit/beeb37a8f3275281be305d2d1afe35ca053e21c0
DIFF: https://github.com/llvm/llvm-project/commit/beeb37a8f3275281be305d2d1afe35ca053e21c0.diff
LOG: [sanitizer] scanf interceptor: fix write size for %mc/%mC/%mS
When the optional assignment-allocation character 'm' (Extension to the
ISO C standard) is present, we currently use internal_strlen(buf)+1 for
all of cCsS[ (D85350). Fix cCS to use the correct size.
Fix https://github.com/llvm/llvm-project/issues/61768
Reviewed By: #sanitizers, vitalybuka
Differential Revision: https://reviews.llvm.org/D158485
Added:
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 220abb89c3beba..24485900644b38 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_format.inc
@@ -340,11 +340,19 @@ 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.
+ // For %mc/%mC/%ms/%m[/%mS, 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);
+ if (char *buf = *(char **)argp) {
+ if (dir.convSpecifier == 'c')
+ size = 1;
+ else if (dir.convSpecifier == 'C')
+ size = sizeof(wchar_t);
+ else if (dir.convSpecifier == 'S')
+ size = (internal_wcslen((wchar_t *)buf) + 1) * sizeof(wchar_t);
+ else // 's' or '['
+ size = internal_strlen(buf) + 1;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);
+ }
}
}
}
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 fa52ccc1994f64..de96e573ab844c 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
@@ -9,14 +9,16 @@
// Tests for *scanf interceptors implementation in sanitizer_common.
//
//===----------------------------------------------------------------------===//
+#include <wchar.h>
+
#include <algorithm>
#include <vector>
+#include "gtest/gtest.h"
#include "interception/interception.h"
-#include "sanitizer_test_utils.h"
-#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_common.h"
-#include "gtest/gtest.h"
+#include "sanitizer_common/sanitizer_libc.h"
+#include "sanitizer_test_utils.h"
using namespace __sanitizer;
@@ -206,21 +208,35 @@ TEST(SanitizerCommonInterceptors, Scanf) {
TEST(SanitizerCommonInterceptors, ScanfAllocate) {
const char *buf = "123456";
+ const wchar_t *wbuf = L"123";
// 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, "%mc", &buf);
+ verifyFormatResults("%mc", 2, scanf_sizes, {P, 1u});
+ }
+ {
+ std::vector<unsigned> scanf_sizes;
+ testScanf3((void *)&scanf_sizes, 2, /*allowGnuMalloc=*/false, "%mC", &wbuf);
+ verifyFormatResults("%mC", 2, scanf_sizes, {P, (unsigned)sizeof(wchar_t)});
+ }
{
std::vector<unsigned> scanf_sizes;
testScanf3((void *)&scanf_sizes, 2, /*allowGnuMalloc=*/false, "%ms", &buf);
- verifyFormatResults("%ms", 2, scanf_sizes,
- {P, (unsigned)(strlen(buf) + 1)});
+ verifyFormatResults("%ms", 2, scanf_sizes, {P, unsigned(strlen(buf) + 1)});
+ scanf_sizes.clear();
+ testScanf3((void *)&scanf_sizes, 2, /*allowGnuMalloc=*/false, "%m[0-9]",
+ &buf);
+ verifyFormatResults("%m[0-9]", 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)});
+ testScanf3((void *)&scanf_sizes, 2, /*allowGnuMalloc=*/false, "%mS", &wbuf);
+ verifyFormatResults("%mS", 2, scanf_sizes,
+ {P, unsigned((wcslen(wbuf) + 1) * sizeof(wchar_t))});
}
}
More information about the llvm-commits
mailing list