| // Copyright 2021 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_SYS_FUZZING_LIBFUZZER_RUNNER_H_ |
| #define SRC_SYS_FUZZING_LIBFUZZER_RUNNER_H_ |
| |
| #include <fuchsia/fuzzer/cpp/fidl.h> |
| #include <lib/fdio/spawn.h> |
| #include <lib/fit/function.h> |
| #include <lib/zx/process.h> |
| |
| #include <memory> |
| #include <string_view> |
| |
| #include "src/sys/fuzzing/common/async-types.h" |
| #include "src/sys/fuzzing/common/input.h" |
| #include "src/sys/fuzzing/common/runner.h" |
| |
| namespace fuzzing { |
| |
| using ::fuchsia::fuzzer::Status; |
| |
| // The concrete implementation of |Runner| for the libfuzzer engine. |
| class LibFuzzerRunner : public Runner { |
| public: |
| ~LibFuzzerRunner() override; |
| |
| // Factory method. |
| static RunnerPtr MakePtr(ExecutorPtr executor); |
| |
| void set_cmdline(const std::vector<std::string>& cmdline) { cmdline_ = cmdline; } |
| void set_verbose(bool verbose) { verbose_ = verbose; } |
| |
| // |Runner| methods. |
| void AddDefaults(Options* options) override; |
| zx_status_t AddToCorpus(CorpusType corpus_type, Input input) override; |
| Input ReadFromCorpus(CorpusType corpus_type, size_t offset) override; |
| zx_status_t ParseDictionary(const Input& input) override; |
| Input GetDictionaryAsInput() const override; |
| Status CollectStatus() override; |
| |
| // Stages of stopping: close sources of new tasks, interrupt the current task, and join it. |
| void Close() override { close_.Run(); } |
| void Interrupt() override { interrupt_.Run(); } |
| void Join() override { join_.Run(); } |
| |
| protected: |
| void ConfigureImpl(const OptionsPtr& options) override; |
| zx_status_t SyncExecute(const Input& input) override; |
| zx_status_t SyncMinimize(const Input& input) override; |
| zx_status_t SyncCleanse(const Input& input) override; |
| zx_status_t SyncFuzz() override; |
| zx_status_t SyncMerge() override; |
| |
| void ClearErrors() override; |
| |
| // Creates the list of actions to perform when spawning libFuzzer. Can be overloaded when testing |
| // to provide additional functionality (e.g. startup handles). |
| virtual std::vector<fdio_spawn_action_t> MakeSpawnActions(); |
| |
| private: |
| explicit LibFuzzerRunner(ExecutorPtr executor); |
| |
| // Construct a set of libFuzzer command-line arguments for the current options. |
| std::vector<std::string> MakeArgs(); |
| |
| // Spawn a libFuzzer process and wait for it to complete. |
| zx_status_t Spawn(const std::vector<std::string>& args); |
| |
| // Interprets the standard error of libFuzzer. |
| void ParseStderr(); |
| |
| // Attempts to interpret the line as containing status information from libFuzzer. |
| // Returns true if |line| is status, false otherwise. |
| bool ParseStatus(const std::string_view& line); |
| |
| // Attempts to interpret the line as containing other information from libFuzzer. |
| void ParseMessage(const std::string_view& line); |
| |
| // Update the list of input files in the live corpus. |
| void ReloadLiveCorpus(); |
| |
| // Stop-related methods. |
| void CloseImpl(); |
| void InterruptImpl(); |
| void JoinImpl(); |
| |
| std::vector<std::string> cmdline_; |
| OptionsPtr options_; |
| |
| // Immutable set of inputs. These will be kept on merge. |
| std::vector<std::string> seed_corpus_; |
| |
| // Dynamic set of inputs. Inputs may be added during fuzzing, and/or may be removed when merging. |
| std::vector<std::string> live_corpus_; |
| |
| bool has_dictionary_ = false; |
| zx::time start_; |
| |
| std::mutex mutex_; |
| bool stopping_ FXL_GUARDED_BY(mutex_) = false; |
| |
| // The spawned subprocess and its (initially invalid) stdio file descriptors. |
| zx::process subprocess_ FXL_GUARDED_BY(mutex_); |
| int piped_stdin_ = -1; |
| int piped_stderr_ = -1; |
| |
| // If true, eachoes the piped stderr to this process's stderr. |
| bool verbose_ = true; |
| |
| Status status_; |
| zx_status_t error_ = ZX_OK; |
| std::string result_input_pathname_; |
| bool minimized_ = false; |
| |
| RunOnce close_; |
| RunOnce interrupt_; |
| RunOnce join_; |
| |
| FXL_DISALLOW_COPY_ASSIGN_AND_MOVE(LibFuzzerRunner); |
| }; |
| |
| } // namespace fuzzing |
| |
| #endif // SRC_SYS_FUZZING_LIBFUZZER_RUNNER_H_ |