Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No public description #1296

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions centipede/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ cc_library(
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_fuzztest//common:remote_file",
"@com_google_fuzztest//common:status_macros",
],
)

Expand Down Expand Up @@ -597,6 +598,7 @@ cc_library(
"@com_google_fuzztest//common:defs",
"@com_google_fuzztest//common:logging",
"@com_google_fuzztest//common:remote_file",
"@com_google_fuzztest//common:status_macros",
],
)

Expand Down Expand Up @@ -770,6 +772,7 @@ cc_library(
"@com_google_fuzztest//common:hash",
"@com_google_fuzztest//common:logging",
"@com_google_fuzztest//common:remote_file",
"@com_google_fuzztest//common:status_macros",
],
)

Expand Down Expand Up @@ -815,6 +818,7 @@ cc_library(
"@com_google_fuzztest//common:hash",
"@com_google_fuzztest//common:logging",
"@com_google_fuzztest//common:remote_file",
"@com_google_fuzztest//common:status_macros",
"@com_google_fuzztest//fuzztest:configuration",
],
)
Expand Down Expand Up @@ -843,6 +847,7 @@ cc_library(
"@com_google_fuzztest//common:defs",
"@com_google_fuzztest//common:logging",
"@com_google_fuzztest//common:remote_file",
"@com_google_fuzztest//common:status_macros",
],
)

Expand Down Expand Up @@ -874,6 +879,7 @@ cc_library(
"@com_google_fuzztest//common:hash",
"@com_google_fuzztest//common:logging",
"@com_google_fuzztest//common:remote_file",
"@com_google_fuzztest//common:status_macros",
],
)

Expand Down
9 changes: 6 additions & 3 deletions centipede/analyze_corpora.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ std::vector<CorpusRecord> ReadCorpora(std::string_view binary_name,
WorkDir workdir(std::string(workdir_path), std::string(binary_name),
std::string(binary_hash), /*my_shard_index=*/0);
std::vector<std::string> corpus_paths;
RemoteGlobMatch(workdir.CorpusFiles().AllShardsGlob(), corpus_paths);
CHECK_OK(
RemoteGlobMatch(workdir.CorpusFiles().AllShardsGlob(), corpus_paths));
std::vector<std::string> features_paths;
RemoteGlobMatch(workdir.FeaturesFiles().AllShardsGlob(), features_paths);
CHECK_OK(
RemoteGlobMatch(workdir.FeaturesFiles().AllShardsGlob(), features_paths));

CHECK_EQ(corpus_paths.size(), features_paths.size());
std::vector<CorpusRecord> corpus;
Expand Down Expand Up @@ -193,7 +195,8 @@ void DumpCoverageReport(const CoverageResults &coverage_results,
std::ostringstream symbol_table_stream;
coverage_symbol_table.WriteToLLVMSymbolizer(symbol_table_stream);

RemoteFileSetContents(coverage_report_path, symbol_table_stream.str());
CHECK_OK(
RemoteFileSetContents(coverage_report_path, symbol_table_stream.str()));
}

AnalyzeCorporaResults AnalyzeCorpora(std::string_view binary_name,
Expand Down
2 changes: 1 addition & 1 deletion centipede/analyze_corpora_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ TEST(DumpCoverageReport, SimpleCoverageResults) {
std::filesystem::path{test_tmpdir} / "covered_symbol_table";
DumpCoverageReport(coverage_results, coverage_report_path);
std::string symbol_table_contents;
RemoteFileGetContents(coverage_report_path, symbol_table_contents);
ASSERT_OK(RemoteFileGetContents(coverage_report_path, symbol_table_contents));

std::istringstream symbol_table_stream(symbol_table_contents);
SymbolTable symbols;
Expand Down
18 changes: 10 additions & 8 deletions centipede/binary_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,16 @@ void BinaryInfo::InitializeFromSanCovBinary(
void BinaryInfo::Read(std::string_view dir) {
std::string symbol_table_contents;
// TODO(b/295978603): move calculation of paths into WorkDir class.
RemoteFileGetContents(
CHECK_OK(RemoteFileGetContents(
(std::filesystem::path(dir) / kSymbolTableFileName).c_str(),
symbol_table_contents);
symbol_table_contents));
std::istringstream symbol_table_stream(symbol_table_contents);
symbols.ReadFromLLVMSymbolizer(symbol_table_stream);

std::string pc_table_contents;
RemoteFileGetContents((std::filesystem::path(dir) / kPCTableFileName).c_str(),
pc_table_contents);
CHECK_OK(RemoteFileGetContents(
(std::filesystem::path(dir) / kPCTableFileName).c_str(),
pc_table_contents));
std::istringstream pc_table_stream(pc_table_contents);
pc_table = ReadPcTable(pc_table_stream);
}
Expand All @@ -140,14 +141,15 @@ void BinaryInfo::Write(std::string_view dir) {
std::ostringstream symbol_table_stream;
symbols.WriteToLLVMSymbolizer(symbol_table_stream);
// TODO(b/295978603): move calculation of paths into WorkDir class.
RemoteFileSetContents(
CHECK_OK(RemoteFileSetContents(
(std::filesystem::path(dir) / kSymbolTableFileName).c_str(),
symbol_table_stream.str());
symbol_table_stream.str()));

std::ostringstream pc_table_stream;
WritePcTable(pc_table, pc_table_stream);
RemoteFileSetContents((std::filesystem::path(dir) / kPCTableFileName).c_str(),
pc_table_stream.str());
CHECK_OK(RemoteFileSetContents(
(std::filesystem::path(dir) / kPCTableFileName).c_str(),
pc_table_stream.str()));
}

} // namespace centipede
2 changes: 1 addition & 1 deletion centipede/blob_file_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void Convert( //
// Verify and prepare source and destination.

CHECK(RemotePathExists(in)) << VV(in);
RemoteMkdir(std::filesystem::path{out}.parent_path().c_str());
CHECK_OK(RemoteMkdir(std::filesystem::path{out}.parent_path().c_str()));

// Open blob file reader and writer.

Expand Down
32 changes: 18 additions & 14 deletions centipede/centipede.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
#include "./common/hash.h"
#include "./common/logging.h"
#include "./common/remote_file.h"
#include "./common/status_macros.h"

namespace centipede {

Expand Down Expand Up @@ -135,8 +136,8 @@ Centipede::Centipede(const Environment &env, CentipedeCallbacks &user_callbacks,

void Centipede::CorpusToFiles(const Environment &env, std::string_view dir) {
std::vector<std::string> sharded_corpus_files;
RemoteGlobMatch(WorkDir{env}.CorpusFiles().AllShardsGlob(),
sharded_corpus_files);
CHECK_OK(RemoteGlobMatch(WorkDir{env}.CorpusFiles().AllShardsGlob(),
sharded_corpus_files));
ExportCorpus(sharded_corpus_files, dir);
}

Expand All @@ -147,7 +148,9 @@ void Centipede::CorpusFromFiles(const Environment &env, std::string_view dir) {
std::vector<std::vector<std::string>> sharded_paths(env.total_shards);
std::vector<std::string> paths;
size_t total_paths = 0;
for (const std::string &path : RemoteListFiles(dir, /*recursively=*/true)) {
const std::vector<std::string> listed_paths =
ValueOrDie(RemoteListFiles(dir, /*recursively=*/true));
for (const std::string &path : listed_paths) {
size_t filename_hash = std::hash<std::string>{}(path);
sharded_paths[filename_hash % env.total_shards].push_back(path);
++total_paths;
Expand Down Expand Up @@ -177,7 +180,7 @@ void Centipede::CorpusFromFiles(const Environment &env, std::string_view dir) {
ByteArray shard_data;
for (const auto &path : sharded_paths[shard]) {
std::string input;
RemoteFileGetContents(path, input);
CHECK_OK(RemoteFileGetContents(path, input));
if (input.empty() || existing_hashes.contains(Hash(input))) {
++inputs_ignored;
continue;
Expand Down Expand Up @@ -533,7 +536,7 @@ void Centipede::GenerateSourceBasedCoverageReport(
auto report_path = wd_.SourceBasedCoverageReportPath(filename_annotation);
LOG(INFO) << "Generate source based coverage report [" << description << "]; "
<< VV(report_path);
RemoteMkdir(report_path);
CHECK_OK(RemoteMkdir(report_path));

std::vector<std::string> raw_profiles = wd_.EnumerateRawCoverageProfiles();

Expand Down Expand Up @@ -574,15 +577,16 @@ void Centipede::GenerateRUsageReport(std::string_view filename_annotation,
class ReportDumper : public RUsageProfiler::ReportSink {
public:
explicit ReportDumper(std::string_view path)
: file_{RemoteFileOpen(path, "w")} {
: file_{*RemoteFileOpen(path, "w")} {
CHECK(file_ != nullptr) << VV(path);
RemoteFileSetWriteBufferSize(file_, 10UL * 1024 * 1024);
CHECK_OK(RemoteFileSetWriteBufferSize(file_, 10UL * 1024 * 1024));
}

~ReportDumper() override { RemoteFileClose(file_); }
~ReportDumper() override { CHECK_OK(RemoteFileClose(file_)); }

ReportDumper &operator<<(std::string_view fragment) override {
RemoteFileAppend(file_, ByteArray{fragment.cbegin(), fragment.cend()});
CHECK_OK(RemoteFileAppend(file_,
ByteArray{fragment.cbegin(), fragment.cend()}));
return *this;
}

Expand Down Expand Up @@ -870,7 +874,7 @@ void Centipede::ReportCrash(std::string_view binary,
if (!user_callbacks_.Execute(binary, {one_input}, one_input_batch_result)) {
auto hash = Hash(one_input);
auto crash_dir = wd_.CrashReproducerDirPath();
RemoteMkdir(crash_dir);
CHECK_OK(RemoteMkdir(crash_dir));
std::string file_path = std::filesystem::path(crash_dir).append(hash);
LOG(INFO) << log_prefix << "Detected crash-reproducing input:"
<< "\nInput index : " << input_idx << "\nInput bytes : "
Expand All @@ -879,7 +883,7 @@ void Centipede::ReportCrash(std::string_view binary,
<< "\nFailure : "
<< one_input_batch_result.failure_description()
<< "\nSaving input to: " << file_path;
RemoteFileSetContents(file_path, one_input);
CHECK_OK(RemoteFileSetContents(file_path, one_input));
return;
}
}
Expand All @@ -898,18 +902,18 @@ void Centipede::ReportCrash(std::string_view binary,
const auto &suspect_input = input_vec[suspect_input_idx];
auto suspect_hash = Hash(suspect_input);
auto crash_dir = wd_.CrashReproducerDirPath();
RemoteMkdir(crash_dir);
CHECK_OK(RemoteMkdir(crash_dir));
std::string save_dir = std::filesystem::path(crash_dir)
.append("crashing_batch-")
.concat(suspect_hash);
RemoteMkdir(save_dir);
CHECK_OK(RemoteMkdir(save_dir));
LOG(INFO) << log_prefix << "Saving used inputs from batch to: " << save_dir;
for (int i = 0; i <= suspect_input_idx; ++i) {
const auto &one_input = input_vec[i];
auto hash = Hash(one_input);
std::string file_path = std::filesystem::path(save_dir).append(
absl::StrFormat("input-%010d-%s", i, hash));
RemoteFileSetContents(file_path, one_input);
CHECK_OK(RemoteFileSetContents(file_path, one_input));
}
}

Expand Down
47 changes: 26 additions & 21 deletions centipede/centipede_interface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "./common/hash.h"
#include "./common/logging.h" // IWYU pragma: keep
#include "./common/remote_file.h"
#include "./common/status_macros.h"
#include "./fuzztest/internal/configuration.h"

namespace centipede {
Expand Down Expand Up @@ -178,7 +179,7 @@ BinaryInfo PopulateBinaryInfoAndSavePCsIfNecessary(
}
if (env.save_binary_info) {
const std::string binary_info_dir = WorkDir{env}.BinaryInfoDirPath();
RemoteMkdir(binary_info_dir);
CHECK_OK(RemoteMkdir(binary_info_dir));
LOG(INFO) << "Serializing binary info to: " << binary_info_dir;
binary_info.Write(binary_info_dir);
}
Expand Down Expand Up @@ -329,11 +330,11 @@ int PruneNonreproducibleAndCountRemainingCrashes(

for (const std::string &crashing_input_file : crashing_input_files) {
ByteArray crashing_input;
RemoteFileGetContents(crashing_input_file, crashing_input);
CHECK_OK(RemoteFileGetContents(crashing_input_file, crashing_input));
if (scoped_callbacks.callbacks()->Execute(env.binary, {crashing_input},
batch_result)) {
// The crash is not reproducible.
RemotePathDelete(crashing_input_file, /*recursively=*/false);
CHECK_OK(RemotePathDelete(crashing_input_file, /*recursively=*/false));
} else {
++num_remaining_crashes;
}
Expand Down Expand Up @@ -435,10 +436,11 @@ int UpdateCorpusDatabaseForFuzzTests(
// This could be a workdir from a failed run that used a different version
// of the binary. We delete it so that we don't have to deal with the
// assumptions under which it is safe to reuse an old workdir.
RemotePathDelete(env.workdir, /*recursively=*/true);
CHECK_OK(RemotePathDelete(env.workdir, /*recursively=*/true));
}
const WorkDir workdir{env};
RemoteMkdir(workdir.CoverageDirPath()); // Implicitly creates the workdir.
CHECK_OK(RemoteMkdir(
workdir.CoverageDirPath())); // Implicitly creates the workdir

// Seed the fuzzing session with the latest coverage corpus from the
// previous fuzzing session.
Expand All @@ -465,35 +467,37 @@ int UpdateCorpusDatabaseForFuzzTests(
Fuzz(env, binary_info, pcs_file_path, callbacks_factory);
if (!stats_root_path.empty()) {
const auto stats_dir = stats_root_path / fuzztest_config.fuzz_tests[i];
RemoteMkdir(stats_dir.c_str());
RemotePathRename(
CHECK_OK(RemoteMkdir(stats_dir.c_str()));
CHECK_OK(RemotePathRename(
workdir.FuzzingStatsPath(),
(stats_dir / absl::StrCat("fuzzing_stats_", execution_stamp))
.c_str());
.c_str()));
}

// Distill and store the coverage corpus.
Distill(env);
if (RemotePathExists(coverage_dir.c_str())) {
// In the future, we will store k latest coverage corpora for some k, but
// for now we only keep the latest one.
RemotePathDelete(coverage_dir.c_str(), /*recursively=*/true);
CHECK_OK(RemotePathDelete(coverage_dir.c_str(), /*recursively=*/true));
}
RemoteMkdir(coverage_dir.c_str());
CHECK_OK(RemoteMkdir(coverage_dir.c_str()));
std::vector<std::string> distilled_corpus_files;
RemoteGlobMatch(workdir.DistilledCorpusFiles().AllShardsGlob(),
distilled_corpus_files);
CHECK_OK(RemoteGlobMatch(workdir.DistilledCorpusFiles().AllShardsGlob(),
distilled_corpus_files));
for (const std::string &corpus_file : distilled_corpus_files) {
const std::string file_name =
std::filesystem::path(corpus_file).filename();
RemotePathRename(corpus_file, (coverage_dir / file_name).c_str());
CHECK_OK(
RemotePathRename(corpus_file, (coverage_dir / file_name).c_str()));
}

const std::filesystem::path crashing_dir = fuzztest_db_path / "crashing";
const std::vector<std::string> crashing_input_files =
// The corpus database layout assumes the crash input files are located
// directly in the crashing subdirectory, so we don't list recursively.
RemoteListFiles(crashing_dir.c_str(), /*recursively=*/false);
ValueOrDie(
RemoteListFiles(crashing_dir.c_str(), /*recursively=*/false));
const int num_remaining_crashes =
PruneNonreproducibleAndCountRemainingCrashes(env, crashing_input_files,
callbacks_factory);
Expand All @@ -505,18 +509,19 @@ int UpdateCorpusDatabaseForFuzzTests(
// The crash reproducer directory may contain subdirectories with
// input files that don't individually cause a crash. We ignore those
// for now and don't list the files recursively.
RemoteListFiles(workdir.CrashReproducerDirPath(),
/*recursively=*/false);
*RemoteListFiles(workdir.CrashReproducerDirPath(),
/*recursively=*/false);
if (!new_crashing_input_files.empty()) {
const std::string crashing_input_file_name =
std::filesystem::path(new_crashing_input_files[0]).filename();
RemoteMkdir(crashing_dir.c_str());
RemotePathRename(new_crashing_input_files[0],
(crashing_dir / crashing_input_file_name).c_str());
CHECK_OK(RemoteMkdir(crashing_dir.c_str()));
CHECK_OK(RemotePathRename(
new_crashing_input_files[0],
(crashing_dir / crashing_input_file_name).c_str()));
}
}
}
RemotePathDelete(base_workdir_path.c_str(), /*recursively=*/true);
CHECK_OK(RemotePathDelete(base_workdir_path.c_str(), /*recursively=*/true));

return EXIT_SUCCESS;
}
Expand Down Expand Up @@ -589,7 +594,7 @@ int CentipedeMain(const Environment &env,

// Create the remote coverage dirs once, before creating any threads.
const auto coverage_dir = WorkDir{env}.CoverageDirPath();
RemoteMkdir(coverage_dir);
CHECK_OK(RemoteMkdir(coverage_dir));
LOG(INFO) << "Coverage dir: " << coverage_dir
<< "; temporary dir: " << tmpdir;

Expand Down
8 changes: 4 additions & 4 deletions centipede/config_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -162,15 +162,15 @@ AugmentedArgvWithCleanup LocalizeConfigFilesInArgv(
if (!path.empty() && !std::filesystem::exists(path)) { // assume remote
// Read the remote file.
std::string contents;
RemoteFileGetContents(path.c_str(), contents);
CHECK_OK(RemoteFileGetContents(path.c_str(), contents));

// Save a temporary local copy.
const std::filesystem::path tmp_dir = TemporaryLocalDirPath();
const std::filesystem::path local_path = tmp_dir / path.filename();
LOG(INFO) << "Localizing remote config: " << VV(path) << VV(local_path);
// NOTE: Ignore "Remote" in the API names here: the paths are always local.
RemoteMkdir(tmp_dir.c_str());
RemoteFileSetContents(local_path.c_str(), contents);
CHECK_OK(RemoteMkdir(tmp_dir.c_str()));
CHECK_OK(RemoteFileSetContents(local_path.c_str(), contents));

// Augment the argv to point at the local copy and ensure it is cleaned up.
replacements.emplace_back(path.c_str(), local_path.c_str());
Expand Down Expand Up @@ -244,7 +244,7 @@ set -x
} else {
file_contents = flags_str;
}
RemoteFileSetContents(path.c_str(), file_contents);
CHECK_OK(RemoteFileSetContents(path.c_str(), file_contents));
}

return path;
Expand Down
Loading
Loading