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()21base::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)28base::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)38TEST(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