• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 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 // Implementation of a proto version of mojo_parse_message_fuzzer that sends
6 // multiple messages per run.
7 
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "base/task_scheduler/task_scheduler.h"
11 #include "mojo/core/embedder/embedder.h"
12 #include "mojo/public/cpp/bindings/binding.h"
13 #include "mojo/public/tools/fuzzers/fuzz_impl.h"
14 #include "mojo/public/tools/fuzzers/mojo_fuzzer.pb.h"
15 #include "testing/libfuzzer/proto/lpm_interface.h"
16 
17 namespace mojo_proto_fuzzer {
18 
FuzzMessage(const MojoFuzzerMessages & mojo_fuzzer_messages,base::RunLoop * run)19 void FuzzMessage(const MojoFuzzerMessages& mojo_fuzzer_messages,
20                  base::RunLoop* run) {
21   fuzz::mojom::FuzzInterfacePtr fuzz;
22   auto impl = std::make_unique<FuzzImpl>(MakeRequest(&fuzz));
23   auto router = impl->binding_.RouterForTesting();
24 
25   for (auto& message_str : mojo_fuzzer_messages.messages()) {
26     // Create a mojo message with the appropriate payload size.
27     mojo::Message message(0, 0, message_str.size(), 0, nullptr);
28     if (message.data_num_bytes() < message_str.size()) {
29       message.payload_buffer()->Allocate(message_str.size() -
30                                          message.data_num_bytes());
31     }
32 
33     // Set the raw message data.
34     memcpy(message.mutable_data(), message_str.data(), message_str.size());
35 
36     // Run the message through header validation, payload validation, and
37     // dispatch to the impl.
38     router->SimulateReceivingMessageForTesting(&message);
39   }
40 
41   // Allow the harness function to return now.
42   run->Quit();
43 }
44 
45 // Environment for the fuzzer. Initializes the mojo EDK and sets up a
46 // TaskScheduler, because Mojo messages must be sent and processed from
47 // TaskRunners.
48 struct Environment {
Environmentmojo_proto_fuzzer::Environment49   Environment() : message_loop(base::MessageLoop::TYPE_UI) {
50     base::TaskScheduler::CreateAndStartWithDefaultParams(
51         "MojoParseMessageFuzzerProcess");
52     mojo::core::Init();
53   }
54 
55   // Message loop to send and handle messages on.
56   base::MessageLoop message_loop;
57 
58   // Suppress mojo validation failure logs.
59   mojo::internal::ScopedSuppressValidationErrorLoggingForTests log_suppression;
60 };
61 
DEFINE_PROTO_FUZZER(const MojoFuzzerMessages & mojo_fuzzer_messages)62 DEFINE_PROTO_FUZZER(const MojoFuzzerMessages& mojo_fuzzer_messages) {
63   static Environment* env = new Environment();
64   // Pass the data along to run on a MessageLoop, and wait for it to finish.
65   base::RunLoop run;
66   env->message_loop.task_runner()->PostTask(
67       FROM_HERE, base::BindOnce(&FuzzMessage, mojo_fuzzer_messages, &run));
68   run.Run();
69 }
70 }  // namespace mojo_proto_fuzzer
71