| // Copyright 2020 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_LIB_FUZZING_FIDL_ENGINE_H_ |
| #define SRC_LIB_FUZZING_FIDL_ENGINE_H_ |
| |
| #include <fuchsia/fuzzer/cpp/fidl.h> |
| #include <lib/async-loop/cpp/loop.h> |
| #include <lib/fidl/cpp/binding_set.h> |
| #include <lib/fxl/macros.h> |
| #include <lib/sync/completion.h> |
| #include <lib/sys/cpp/component_context.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <memory> |
| |
| #include "coverage.h" |
| #include "data-provider.h" |
| |
| namespace fuzzing { |
| namespace { |
| |
| using ::fuchsia::fuzzer::Engine; |
| using ::fuchsia::fuzzer::LlvmFuzzerPtr; |
| |
| } // namespace |
| |
| // This class integrates the Coverage, DataProvider, and LlvmFuzzer FIDL services into a single |
| // object that can perform fuzzing iterations. See also libfuzzer.cc, which integrates the |
| // libFuzzer compiler runtime with this class. |
| class EngineImpl : public Engine { |
| public: |
| // Singleton. Tests can avoid the engine starting a dispatch loop by calling this with |
| // |autoconnect| set to false before any other calls, preferably by using |UseContext| below. |
| static EngineImpl *GetInstance(bool autoconnect = true); |
| virtual ~EngineImpl(); |
| |
| // Helper for getting a test instance of Engine that uses the test's |context| and |dispatcher|. |
| static void UseContext(std::unique_ptr<sys::ComponentContext> context) { |
| GetInstance(false)->UseContextImpl(std::move(context)); |
| } |
| |
| // Accessors |
| AggregatedCoverage &coverage() { return coverage_; } |
| DataProviderImpl &data_provider() { return data_provider_; } |
| |
| // Sets the LlvmFuzzer service this engine is connected to. Used for testing (autoconnect=false). |
| zx_status_t SetLlvmFuzzer(LlvmFuzzerPtr fuzzer); |
| |
| // FIDL methods |
| void Start(std::vector<std::string> options, StartCallback callback) override; |
| |
| // LLVM C ABI functions |
| // See https://github.com/llvm/llvm-project/blob/HEAD/compiler-rt/lib/fuzzer/FuzzerInterface.h |
| int Initialize(int *argc, char ***argv); |
| int TestOneInput(const uint8_t *data, size_t size); |
| |
| // Stops the engine and invokes the callback passed to |Start|. |
| void Stop(zx_status_t status); |
| |
| private: |
| explicit EngineImpl(bool autoconnect); |
| |
| void UseContextImpl(std::unique_ptr<sys::ComponentContext> context); |
| |
| // FIDL dispatcher loop. Null when testing. |
| std::unique_ptr<async::Loop> loop_; |
| |
| std::unique_ptr<sys::ComponentContext> context_; |
| async_dispatcher_t *dispatcher_; |
| |
| AggregatedCoverage coverage_; |
| DataProviderImpl data_provider_; |
| LlvmFuzzerPtr llvm_fuzzer_; |
| |
| // LibFuzzer options and a command line used for passing them to libFuzzer. |
| // See https://llvm.org/docs/LibFuzzer.html#options |
| std::vector<std::string> options_; |
| std::vector<char *> argv_; |
| |
| // Blocks |Initialize| and |TestOneInput|| until |Start| has been called. |
| sync_completion_t sync_; |
| |
| // Callback used to return status when the engine stops. |
| StartCallback callback_; |
| |
| FXL_DISALLOW_COPY_ASSIGN_AND_MOVE(EngineImpl); |
| }; |
| |
| } // namespace fuzzing |
| |
| #endif // SRC_LIB_FUZZING_FIDL_ENGINE_H_ |