blob: 23d9302ce21ba30df5795e56382d78eca655cab2 [file]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include "base/containers/span.h"
#include "base/functional/callback_helpers.h"
#include "base/message_loop/message_pump_type.h"
#include "base/no_destructor.h"
#include "base/numerics/byte_conversions.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_executor.h"
#include "build/build_config.h"
#include "mojo/core/channel.h"
#include "mojo/core/connection_params.h"
#include "mojo/core/fuzzing_utils.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "testing/libfuzzer/libfuzzer_base_wrappers.h"
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#endif
DEFINE_LLVM_FUZZER_TEST_ONE_INPUT_SPAN(base::span<const uint8_t> payload) {
static base::NoDestructor<mojo::core::Environment> environment;
mojo::PlatformChannel channel;
mojo::core::FakeChannelDelegate receiver_delegate{/*is_ipcz_transport=*/true};
using mojo::core::Channel;
auto receiver =
Channel::Create(&receiver_delegate,
mojo::core::ConnectionParams(channel.TakeLocalEndpoint()),
Channel::HandlePolicy::kRejectHandles,
environment->main_thread_task_executor.task_runner());
receiver->Start();
mojo::core::FakeChannelDelegate sender_delegate{/*is_ipcz_transport=*/true};
auto sender = Channel::Create(
&sender_delegate,
mojo::core::ConnectionParams(channel.TakeRemoteEndpoint()),
Channel::HandlePolicy::kRejectHandles,
environment->main_thread_task_executor.task_runner());
sender->Start();
// Fuzz ipcz message parsing from raw data.
sender->Write(Channel::Message::CreateRawForFuzzing(payload));
base::RunLoop().RunUntilIdle();
// Fuzz handling valid ipcz messages.
auto message_type = Channel::Message::MessageType::NORMAL;
constexpr size_t kMessageTypeSize = sizeof(message_type);
if (payload.size() >= kMessageTypeSize) {
message_type = static_cast<Channel::Message::MessageType>(
base::U16FromLittleEndian(payload.first<kMessageTypeSize>()));
payload = payload.subspan(kMessageTypeSize);
}
uint32_t sequence_number = 0;
constexpr size_t kSequenceNumberTypeSize = sizeof(sequence_number);
if (payload.size() >= kSequenceNumberTypeSize) {
sequence_number =
base::U32FromLittleEndian(payload.first<kSequenceNumberTypeSize>());
payload = payload.subspan(kSequenceNumberTypeSize);
}
sender->Write(Channel::Message::CreateIpczMessage(payload, {}, message_type,
sequence_number));
base::RunLoop().RunUntilIdle();
sender->ShutDown();
sender.reset();
receiver->ShutDown();
receiver.reset();
base::RunLoop().RunUntilIdle();
return 0;
}