Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(276)

Unified Diff: tools/ipc_fuzzer/mutate/fuzzer_main.cc

Issue 1000373004: Combine traits for IPC mutation and generation fuzzing plus other refactoring. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Define frequency as a constant and reorder arguments in ipc_fuzzer_gen.py Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/ipc_fuzzer/mutate/fuzzer.cc ('k') | tools/ipc_fuzzer/mutate/generate.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/ipc_fuzzer/mutate/fuzzer_main.cc
diff --git a/tools/ipc_fuzzer/mutate/fuzzer_main.cc b/tools/ipc_fuzzer/mutate/fuzzer_main.cc
new file mode 100644
index 0000000000000000000000000000000000000000..db777bac5bf4b87d9de6ebf60fcd14ce14ca6707
--- /dev/null
+++ b/tools/ipc_fuzzer/mutate/fuzzer_main.cc
@@ -0,0 +1,245 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <iostream>
+#include <set>
+#include <vector>
+
+#include "base/command_line.h"
+#include "base/strings/string_split.h"
+#include "ipc/ipc_message_macros.h"
+#include "tools/ipc_fuzzer/message_lib/message_file.h"
+#include "tools/ipc_fuzzer/mutate/fuzzer.h"
+#include "tools/ipc_fuzzer/mutate/generator.h"
+#include "tools/ipc_fuzzer/mutate/mutator.h"
+#include "tools/ipc_fuzzer/mutate/rand_util.h"
+
+namespace ipc_fuzzer {
+
+namespace {
+
+// TODO(mbarbella): Check to see if this value is actually reasonable.
+const int kFrequency = 23;
+
+const char kCountSwitch[] = "count";
+const char kCountSwitchHelp[] =
+ "Number of messages to generate (generator).";
+
+const char kFrequencySwitch[] = "frequency";
+const char kFrequencySwitchHelp[] =
+ "Probability of mutation; tweak every 1/|q| times (mutator).";
+
+const char kFuzzerNameSwitch[] = "fuzzer-name";
+const char kFuzzerNameSwitchHelp[] =
+ "Select generator, mutator, or no-op fuzzer. Default: generator";
+
+const char kHelpSwitch[] = "help";
+const char kHelpSwitchHelp[] =
+ "Show this message.";
+
+const char kPermuteSwitch[] = "permute";
+const char kPermuteSwitchHelp[] =
+ "Randomly shuffle the order of all messages (mutator).";
+
+const char kTypeListSwitch[] = "type-list";
+const char kTypeListSwitchHelp[] =
+ "Explicit list of the only message-ids to mutate (mutator).";
+
+void usage() {
+ std::cerr << "Mutate messages from an exiting message file.\n";
+
+ std::cerr << "Usage:\n"
+ << " ipc_fuzzer"
+ << " [--" << kCountSwitch << "=c]"
+ << " [--" << kFrequencySwitch << "=q]"
+ << " [--" << kFuzzerNameSwitch << "=f]"
+ << " [--" << kHelpSwitch << "]"
+ << " [--" << kTypeListSwitch << "=x,y,z...]"
+ << " [--" << kPermuteSwitch << "]"
+ << " [infile (mutation only)] outfile\n";
+
+ std::cerr
+ << " --" << kCountSwitch << " - " << kCountSwitchHelp << "\n"
+ << " --" << kFrequencySwitch << " - " << kFrequencySwitchHelp << "\n"
+ << " --" << kFuzzerNameSwitch << " - " << kFuzzerNameSwitchHelp << "\n"
+ << " --" << kHelpSwitch << " - " << kHelpSwitchHelp << "\n"
+ << " --" << kTypeListSwitch << " - " << kTypeListSwitchHelp << "\n"
+ << " --" << kPermuteSwitch << " - " << kPermuteSwitchHelp << "\n";
+}
+
+} // namespace
+
+class FuzzerFactory {
+ public:
+ static Fuzzer *Create(const std::string& name, int frequency) {
+ if (name == "default")
+ return new Generator();
+
+ if (name == "generate")
+ return new Generator();
+
+ if (name == "mutate")
+ return new Mutator(frequency);
+
+ if (name == "no-op")
+ return new NoOpFuzzer();
+
+ std::cerr << "No such fuzzer: " << name << "\n";
+ return 0;
+ }
+};
+
+static IPC::Message* RewriteMessage(
+ IPC::Message* message,
+ Fuzzer* fuzzer,
+ FuzzerFunctionMap* map) {
+ FuzzerFunctionMap::iterator it = map->find(message->type());
+ if (it == map->end()) {
+ // This usually indicates a missing message file in all_messages.h, or
+ // that the message dump file is taken from a different revision of
+ // chromium from this executable.
+ std::cerr << "Unknown message type: ["
+ << IPC_MESSAGE_ID_CLASS(message->type()) << ", "
+ << IPC_MESSAGE_ID_LINE(message->type()) << "].\n";
+ return 0;
+ }
+
+ return (*it->second)(message, fuzzer);
+}
+
+int Generate(base::CommandLine* cmd, Fuzzer* fuzzer) {
+ base::CommandLine::StringVector args = cmd->GetArgs();
+ if (args.size() != 1) {
+ usage();
+ return EXIT_FAILURE;
+ }
+ base::FilePath::StringType output_file_name = args[0];
+
+ int message_count = 1000;
+ if (cmd->HasSwitch(kCountSwitch))
+ message_count = atoi(cmd->GetSwitchValueASCII(kCountSwitch).c_str());
+
+ MessageVector message_vector;
+ int bad_count = 0;
+ if (message_count < 0) {
+ // Enumerate them all.
+ for (size_t i = 0; i < g_function_vector.size(); ++i) {
+ if (IPC::Message* new_message = (*g_function_vector[i])(NULL, fuzzer))
+ message_vector.push_back(new_message);
+ else
+ bad_count += 1;
+ }
+ } else {
+ // Fuzz a random batch.
+ for (int i = 0; i < message_count; ++i) {
+ size_t index = RandInRange(g_function_vector.size());
+ if (IPC::Message* new_message = (*g_function_vector[index])(NULL, fuzzer))
+ message_vector.push_back(new_message);
+ else
+ bad_count += 1;
+ }
+ }
+
+ std::cerr << "Failed to generate " << bad_count << " messages.\n";
+ if (!MessageFile::Write(base::FilePath(output_file_name), message_vector))
+ return EXIT_FAILURE;
+ return EXIT_SUCCESS;
+}
+
+int Mutate(base::CommandLine* cmd, Fuzzer* fuzzer) {
+ base::CommandLine::StringVector args = cmd->GetArgs();
+ if (args.size() != 2) {
+ usage();
+ return EXIT_FAILURE;
+ }
+ base::FilePath::StringType input_file_name = args[0];
+ base::FilePath::StringType output_file_name = args[1];
+
+ bool permute = cmd->HasSwitch(kPermuteSwitch);
+
+ std::string type_string_list = cmd->GetSwitchValueASCII(kTypeListSwitch);
+ std::vector<std::string> type_string_vector;
+ base::SplitString(type_string_list, ',', &type_string_vector);
+ std::set<uint32> type_set;
+ for (size_t i = 0; i < type_string_vector.size(); ++i) {
+ type_set.insert(atoi(type_string_vector[i].c_str()));
+ }
+
+ FuzzerFunctionMap fuzz_function_map;
+ PopulateFuzzerFunctionMap(&fuzz_function_map);
+
+ MessageVector message_vector;
+ if (!MessageFile::Read(base::FilePath(input_file_name), &message_vector))
+ return EXIT_FAILURE;
+
+ for (size_t i = 0; i < message_vector.size(); ++i) {
+ IPC::Message* msg = message_vector[i];
+ // If an explicit type set is specified, make sure we should be mutating
+ // this message type on this run.
+ if (!type_set.empty() && type_set.end() == std::find(
+ type_set.begin(), type_set.end(), msg->type())) {
+ continue;
+ }
+ IPC::Message* new_message = RewriteMessage(msg, fuzzer, &fuzz_function_map);
+ if (new_message) {
+ IPC::Message* old_message = message_vector[i];
+ delete old_message;
+ message_vector[i] = new_message;
+ }
+ }
+
+ if (permute) {
+ std::random_shuffle(message_vector.begin(), message_vector.end(),
+ RandInRange);
+ }
+
+ if (!MessageFile::Write(base::FilePath(output_file_name), message_vector))
+ return EXIT_FAILURE;
+ return EXIT_SUCCESS;
+}
+
+int FuzzerMain(int argc, char** argv) {
+ base::CommandLine::Init(argc, argv);
+ base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
+ base::CommandLine::StringVector args = cmd->GetArgs();
+
+ if (args.size() == 0 || args.size() > 2 || cmd->HasSwitch(kHelpSwitch)) {
+ usage();
+ return EXIT_FAILURE;
+ }
+
+ InitRand();
+
+ PopulateFuzzerFunctionVector(&g_function_vector);
+ std::cerr << "Counted " << g_function_vector.size()
+ << " distinct messages present in chrome.\n";
+
+ std::string fuzzer_name = "default";
+ if (cmd->HasSwitch(kFuzzerNameSwitch))
+ fuzzer_name = cmd->GetSwitchValueASCII(kFuzzerNameSwitch);
+
+ int frequency = kFrequency;
+ if (cmd->HasSwitch(kFrequencySwitch))
+ frequency = atoi(cmd->GetSwitchValueASCII(kFrequencySwitch).c_str());
+
+ Fuzzer* fuzzer = FuzzerFactory::Create(fuzzer_name, frequency);
+ if (!fuzzer)
+ return EXIT_FAILURE;
+
+ int result;
+ base::FilePath::StringType output_file_name;
+ if (fuzzer_name == "default" || fuzzer_name == "generate") {
+ result = Generate(cmd, fuzzer);
+ } else {
+ result = Mutate(cmd, fuzzer);
+ }
+
+ return result;
+}
+
+} // namespace ipc_fuzzer
+
+int main(int argc, char** argv) {
+ return ipc_fuzzer::FuzzerMain(argc, argv);
+}
« no previous file with comments | « tools/ipc_fuzzer/mutate/fuzzer.cc ('k') | tools/ipc_fuzzer/mutate/generate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698