channel_fuzzer.cc 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. #include <stdint.h>
  5. #include "base/callback_helpers.h"
  6. #include "base/message_loop/message_pump_type.h"
  7. #include "base/no_destructor.h"
  8. #include "base/run_loop.h"
  9. #include "base/task/single_thread_task_executor.h"
  10. #include "build/build_config.h"
  11. #include "mojo/core/channel.h"
  12. #include "mojo/core/connection_params.h"
  13. #include "mojo/core/entrypoints.h"
  14. #include "mojo/public/cpp/platform/platform_channel.h"
  15. #if BUILDFLAG(IS_WIN)
  16. #include <windows.h>
  17. #endif
  18. // A fake delegate for each Channel endpoint. By the time an incoming message
  19. // reaches a Delegate, all interesting message parsing at the lowest protocol
  20. // layer has already been done by the receiving Channel implementation, so this
  21. // doesn't need to do any work.
  22. class FakeChannelDelegate : public mojo::core::Channel::Delegate {
  23. public:
  24. FakeChannelDelegate() = default;
  25. ~FakeChannelDelegate() override = default;
  26. void OnChannelMessage(const void* payload,
  27. size_t payload_size,
  28. std::vector<mojo::PlatformHandle> handles) override {}
  29. void OnChannelError(mojo::core::Channel::Error error) override {}
  30. };
  31. // Message deserialization may register handles in the global handle table. We
  32. // need to initialize Core for that to be OK.
  33. struct Environment {
  34. Environment() : main_thread_task_executor(base::MessagePumpType::IO) {
  35. mojo::core::InitializeCore();
  36. }
  37. base::SingleThreadTaskExecutor main_thread_task_executor;
  38. };
  39. extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) {
  40. static base::NoDestructor<Environment> environment;
  41. // Platform-specific implementation of an OS IPC primitive that is normally
  42. // used to carry messages between processes.
  43. mojo::PlatformChannel channel;
  44. FakeChannelDelegate receiver_delegate;
  45. auto receiver = mojo::core::Channel::Create(
  46. &receiver_delegate,
  47. mojo::core::ConnectionParams(channel.TakeLocalEndpoint()),
  48. mojo::core::Channel::HandlePolicy::kRejectHandles,
  49. environment->main_thread_task_executor.task_runner());
  50. #if BUILDFLAG(IS_WIN)
  51. // On Windows, it's important that the receiver behaves like a broker process
  52. // receiving messages from a non-broker process. This is because that case can
  53. // safely handle invalid HANDLE attachments without crashing. The same is not
  54. // true for messages going in the reverse direction (where the non-broker
  55. // receiver has to assume that the broker has already duplicated the HANDLE
  56. // into the non-broker's process), but fuzzing that direction is not
  57. // interesting since a compromised broker process has much bigger problems.
  58. receiver->set_remote_process(base::Process::Current());
  59. #endif
  60. receiver->Start();
  61. FakeChannelDelegate sender_delegate;
  62. auto sender = mojo::core::Channel::Create(
  63. &sender_delegate,
  64. mojo::core::ConnectionParams(channel.TakeRemoteEndpoint()),
  65. mojo::core::Channel::HandlePolicy::kRejectHandles,
  66. environment->main_thread_task_executor.task_runner());
  67. sender->Start();
  68. sender->Write(mojo::core::Channel::Message::CreateRawForFuzzing(
  69. base::make_span(data, size)));
  70. // Make sure |receiver| does whatever work it's gonna do in response to our
  71. // message. By the time the loop goes idle, all parsing will be done.
  72. base::RunLoop().RunUntilIdle();
  73. // Clean up our channels so we don't leak their underlying OS primitives.
  74. sender->ShutDown();
  75. sender.reset();
  76. receiver->ShutDown();
  77. receiver.reset();
  78. base::RunLoop().RunUntilIdle();
  79. return 0;
  80. }