Home | History | Annotate | Download | only in fuzzers
      1 // Copyright 2017 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/message_loop/message_loop.h"
      6 #include "base/run_loop.h"
      7 #include "base/task_scheduler/task_scheduler.h"
      8 #include "mojo/core/embedder/embedder.h"
      9 #include "mojo/public/cpp/bindings/binding.h"
     10 #include "mojo/public/tools/fuzzers/fuzz_impl.h"
     11 
     12 void FuzzMessage(const uint8_t* data, size_t size, base::RunLoop* run) {
     13   fuzz::mojom::FuzzInterfacePtr fuzz;
     14   auto impl = std::make_unique<FuzzImpl>(MakeRequest(&fuzz));
     15   auto router = impl->binding_.RouterForTesting();
     16 
     17   /* Create a mojo message with the appropriate payload size. */
     18   mojo::Message message(0, 0, size, 0, nullptr);
     19   if (message.data_num_bytes() < size) {
     20     message.payload_buffer()->Allocate(size - message.data_num_bytes());
     21   }
     22 
     23   /* Set the raw message data. */
     24   memcpy(message.mutable_data(), data, size);
     25 
     26   /* Run the message through header validation, payload validation, and
     27    * dispatch to the impl. */
     28   router->SimulateReceivingMessageForTesting(&message);
     29 
     30   /* Allow the harness function to return now. */
     31   run->Quit();
     32 }
     33 
     34 /* Environment for the fuzzer. Initializes the mojo EDK and sets up a
     35  * TaskScheduler, because Mojo messages must be sent and processed from
     36  * TaskRunners. */
     37 struct Environment {
     38   Environment() : message_loop(base::MessageLoop::TYPE_UI) {
     39     base::TaskScheduler::CreateAndStartWithDefaultParams(
     40         "MojoParseMessageFuzzerProcess");
     41     mojo::core::Init();
     42   }
     43 
     44   /* Message loop to send and handle messages on. */
     45   base::MessageLoop message_loop;
     46 
     47   /* Suppress mojo validation failure logs. */
     48   mojo::internal::ScopedSuppressValidationErrorLoggingForTests log_suppression;
     49 };
     50 
     51 // Entry point for LibFuzzer.
     52 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
     53   static Environment* env = new Environment();
     54   /* Pass the data along to run on a MessageLoop, and wait for it to finish. */
     55   base::RunLoop run;
     56   env->message_loop.task_runner()->PostTask(
     57       FROM_HERE, base::BindOnce(&FuzzMessage, data, size, &run));
     58   run.Run();
     59 
     60   return 0;
     61 }
     62