• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <string>
6 
7 #include "base/base_paths.h"
8 #include "base/command_line.h"
9 #include "base/files/file_path.h"
10 #include "base/path_service.h"
11 #include "base/process/launch.h"
12 #include "base/sanitizer_buildflags.h"
13 #include "base/strings/string_util.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 
17 namespace {
18 
19 using testing::ContainsRegex;
20 
FuzzerPath()21 base::FilePath FuzzerPath() {
22   base::FilePath out_dir;
23   base::PathService::Get(base::DIR_OUT_TEST_DATA_ROOT, &out_dir);
24 
25   return out_dir.AppendASCII("stacktrace_test_fuzzer");
26 }
27 
FuzzerInputPath(std::string_view input_file)28 base::FilePath FuzzerInputPath(std::string_view input_file) {
29   base::FilePath src_dir;
30   base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_dir);
31 
32   return src_dir.AppendASCII("testing/libfuzzer/tests/data")
33       .AppendASCII(input_file);
34 }
35 
36 // The UaF is not detected under UBSan, which happily runs the fuzzer forever.
37 #if !BUILDFLAG(IS_UBSAN) && !BUILDFLAG(IS_UBSAN_SECURITY)
TEST(FuzzerStacktraceTest,SymbolizesUAF)38 TEST(FuzzerStacktraceTest, SymbolizesUAF) {
39   base::CommandLine cmd(FuzzerPath());
40   cmd.AppendArgPath(FuzzerInputPath("uaf"));
41 
42   std::string output;
43   EXPECT_FALSE(base::GetAppOutputAndError(cmd, &output));  // Target crashes.
44 
45 // TODO(https://crbug.com/40948553): Get MSan fuzzer build to work and expect
46 // the correct output here.
47 #if defined(ADDRESS_SANITIZER)
48   constexpr std::string_view kOutput = R"(
49 ERROR: AddressSanitizer: heap-use-after-free on address 0x[0-9a-f]+.*
50 READ of size 4 at 0x[0-9a-f]+ thread T[0-9]+
51     #0 0x[0-9a-f]+ in TriggerUAF\(\) testing/libfuzzer/tests/stacktrace_test_fuzzer.cc:[0-9]+:[0-9]+
52   )";
53   EXPECT_THAT(output, ContainsRegex(
54                           base::TrimWhitespaceASCII(kOutput, base::TRIM_ALL)));
55 #endif
56 }
57 #endif  // !BUILDFLAG(IS_UBSAN) && !BUILDFLAG(IS_UBSAN_SECURITY)
58 
59 }  // namespace
60