|  | // WARNING: This file is machine generated by fidlgen. | 
|  |  | 
|  | #include <fidl/test/protocolrequest/cpp/libfuzzer.h> | 
|  | #include <lib/async-loop/cpp/loop.h> | 
|  | #include <lib/async-loop/default.h> | 
|  | #include <lib/fidl/cpp/fuzzing/fuzzer.h> | 
|  | #include <lib/fidl/cpp/interface_ptr.h> | 
|  | #include <lib/zx/channel.h> | 
|  | #include <zircon/errors.h> | 
|  | #include <zircon/syscalls.h> | 
|  | #include <zircon/types.h> | 
|  |  | 
|  | using namespace ::fuzzing; | 
|  | using namespace ::fidl::test::protocolrequest; | 
|  |  | 
|  | // Add //build/fuzzing:fuzzing_verbose_logging to a GN target's configs to | 
|  | // enable. | 
|  | #if FUZZING_VERBOSE_LOGGING | 
|  | #include <stdio.h> | 
|  | #define xprintf(fmt...) printf(fmt) | 
|  | #else | 
|  | #define xprintf(fmt...) \ | 
|  | do {                  \ | 
|  | } while (0) | 
|  | #endif | 
|  |  | 
|  | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data_, size_t size_) { | 
|  | static ::async::Loop* loop_ = nullptr; | 
|  |  | 
|  | if (loop_ == nullptr) { | 
|  | xprintf("Starting client async loop\n"); | 
|  | loop_ = new ::async::Loop(&kAsyncLoopConfigAttachToCurrentThread); | 
|  | } | 
|  |  | 
|  | // Must fuzz some protocol; first two bytes used to select protocol and | 
|  | // method. | 
|  | if (size_ < 2) { | 
|  | xprintf("Early exit: Input too small: %zu\n", size_); | 
|  | return 0; | 
|  | } | 
|  | size_ -= 2; | 
|  |  | 
|  | uint8_t protocol_selector_ = data_[0]; | 
|  | uint8_t protocol_selection_ = protocol_selector_ % 2; | 
|  |  | 
|  | xprintf("Starting fuzzer with %zu bytes of data\n", size_); | 
|  |  | 
|  | // Hardcode mutually-exclusive if blocks that selects exactly one protocol. | 
|  | zx_status_t status_; | 
|  | if (protocol_selection_ == 0) { | 
|  | #if !defined(PROTOCOL_fidl_test_protocolrequest_Parent) | 
|  | // Selected protocol from FIDL file that is not part of this fuzzer. | 
|  | xprintf( | 
|  | "Early exit: Chose disabled protocol: " | 
|  | "fidl_test_protocolrequest_Parent\n"); | 
|  | return 0; | 
|  | #else | 
|  |  | 
|  | ::fidl::InterfacePtr< ::fidl::test::protocolrequest::Parent> protocol_; | 
|  |  | 
|  | xprintf("Starting fidl_test_protocolrequest_Parent service\n"); | 
|  | ::fidl::fuzzing::Fuzzer< ::fidl::test::protocolrequest::Parent> fuzzer_( | 
|  | loop_->dispatcher()); | 
|  | if ((status_ = fuzzer_.Init()) != ZX_OK) { | 
|  | xprintf("Early exit: fuzzer.Init returned bad status: %d\n", status_); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | if ((status_ = fuzzer_.BindService()) != ZX_OK) { | 
|  | xprintf("Early exit: fuzzer.BindService returned bad status: %d\n", | 
|  | status_); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | if ((status_ = fuzzer_.BindClient(&protocol_, loop_->dispatcher())) != | 
|  | ZX_OK) { | 
|  | xprintf("Early exit: fuzzer.BindClient returned bad status: %d\n", | 
|  | status_); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | FuzzInput src_(data_, size_); | 
|  |  | 
|  | uint8_t method_selector_ = data_[1]; | 
|  | uint8_t method_selection_ = method_selector_ % 4; | 
|  | if (method_selection_ == 2) { | 
|  | #if !(ALL_METHODS || defined(METHOD_TakeChild)) | 
|  | // Selected method from protocol that is not part of this fuzzer. | 
|  | xprintf("Early exit: Chose disabled method: TakeChild\n"); | 
|  | return 0; | 
|  | #else | 
|  | const size_t min_size_ = MinSize< | 
|  | ::fidl::InterfaceHandle< ::fidl::test::protocolrequest::Child> >(); | 
|  |  | 
|  | // Must have enough bytes for input. | 
|  | if (size_ < min_size_) { | 
|  | xprintf("Early exit: Input size too small: %zu < %zu\n", size_, | 
|  | min_size_); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | const size_t slack_size_ = size_ - min_size_; | 
|  | const size_t slack_size_per_param = slack_size_ / 1; | 
|  |  | 
|  | xprintf("Allocating parameters with %zu bytes (%zu bytes each)\n", | 
|  | slack_size_, slack_size_per_param); | 
|  |  | 
|  | size_t param_size_; | 
|  | param_size_ = MinSize< ::fidl::InterfaceHandle< | 
|  | ::fidl::test::protocolrequest::Child> >() + | 
|  | slack_size_per_param; | 
|  | xprintf( | 
|  | "Allocating %zu bytes for " | 
|  | "::fidl::InterfaceHandle<::fidl::test::protocolrequest::Child> c\n", | 
|  | param_size_); | 
|  | ::fidl::InterfaceHandle< ::fidl::test::protocolrequest::Child> c = | 
|  | Allocate< ::fidl::InterfaceHandle< | 
|  | ::fidl::test::protocolrequest::Child> >{}(&src_, ¶m_size_); | 
|  |  | 
|  | xprintf("Invoking method fidl_test_protocolrequest_Parent.TakeChild\n"); | 
|  | protocol_->TakeChild(std::move(c)); | 
|  | #endif | 
|  | } | 
|  | if (method_selection_ == 3) { | 
|  | #if !(ALL_METHODS || defined(METHOD_TakeChildRequest)) | 
|  | // Selected method from protocol that is not part of this fuzzer. | 
|  | xprintf("Early exit: Chose disabled method: TakeChildRequest\n"); | 
|  | return 0; | 
|  | #else | 
|  | const size_t min_size_ = MinSize< | 
|  | ::fidl::InterfaceRequest< ::fidl::test::protocolrequest::Child> >(); | 
|  |  | 
|  | // Must have enough bytes for input. | 
|  | if (size_ < min_size_) { | 
|  | xprintf("Early exit: Input size too small: %zu < %zu\n", size_, | 
|  | min_size_); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | const size_t slack_size_ = size_ - min_size_; | 
|  | const size_t slack_size_per_param = slack_size_ / 1; | 
|  |  | 
|  | xprintf("Allocating parameters with %zu bytes (%zu bytes each)\n", | 
|  | slack_size_, slack_size_per_param); | 
|  |  | 
|  | size_t param_size_; | 
|  | param_size_ = MinSize< ::fidl::InterfaceRequest< | 
|  | ::fidl::test::protocolrequest::Child> >() + | 
|  | slack_size_per_param; | 
|  | xprintf( | 
|  | "Allocating %zu bytes for " | 
|  | "::fidl::InterfaceRequest<::fidl::test::protocolrequest::Child> r\n", | 
|  | param_size_); | 
|  | ::fidl::InterfaceRequest< ::fidl::test::protocolrequest::Child> r = | 
|  | Allocate< ::fidl::InterfaceRequest< | 
|  | ::fidl::test::protocolrequest::Child> >{}(&src_, ¶m_size_); | 
|  |  | 
|  | xprintf( | 
|  | "Invoking method " | 
|  | "fidl_test_protocolrequest_Parent.TakeChildRequest\n"); | 
|  | protocol_->TakeChildRequest(std::move(r)); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | loop_->RunUntilIdle(); | 
|  |  | 
|  | if ((status_ = fuzzer_.WaitForCallback()) != ZX_OK) { | 
|  | xprintf("fuzzer.WaitForCallback returned bad status: %d\n", status_); | 
|  | } | 
|  |  | 
|  | protocol_.Unbind(); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | xprintf("Fuzzer stopped!\n"); | 
|  |  | 
|  | return 0; | 
|  | } |