// Copyright 2017 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 "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/task_scheduler/task_scheduler.h" #include "mojo/core/embedder/embedder.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/tools/fuzzers/fuzz_impl.h" void FuzzMessage(const uint8_t* data, size_t size, base::RunLoop* run) { fuzz::mojom::FuzzInterfacePtr fuzz; auto impl = std::make_unique<FuzzImpl>(MakeRequest(&fuzz)); auto router = impl->binding_.RouterForTesting(); /* Create a mojo message with the appropriate payload size. */ mojo::Message message(0, 0, size, 0, nullptr); if (message.data_num_bytes() < size) { message.payload_buffer()->Allocate(size - message.data_num_bytes()); } /* Set the raw message data. */ memcpy(message.mutable_data(), data, size); /* Run the message through header validation, payload validation, and * dispatch to the impl. */ router->SimulateReceivingMessageForTesting(&message); /* Allow the harness function to return now. */ run->Quit(); } /* Environment for the fuzzer. Initializes the mojo EDK and sets up a * TaskScheduler, because Mojo messages must be sent and processed from * TaskRunners. */ struct Environment { Environment() : message_loop(base::MessageLoop::TYPE_UI) { base::TaskScheduler::CreateAndStartWithDefaultParams( "MojoParseMessageFuzzerProcess"); mojo::core::Init(); } /* Message loop to send and handle messages on. */ base::MessageLoop message_loop; /* Suppress mojo validation failure logs. */ mojo::internal::ScopedSuppressValidationErrorLoggingForTests log_suppression; }; // Entry point for LibFuzzer. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { static Environment* env = new Environment(); /* Pass the data along to run on a MessageLoop, and wait for it to finish. */ base::RunLoop run; env->message_loop.task_runner()->PostTask( FROM_HERE, base::BindOnce(&FuzzMessage, data, size, &run)); run.Run(); return 0; }