blob: 1c72f7c6915410407d23634df9b834681c67ecc1 [file] [log] [blame]
// Copyright 2021 The Chromium OS 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/check.h>
#include <base/threading/thread_task_runner_handle.h>
#include <brillo/daemons/daemon.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <sysexits.h>
#include <cstddef>
#include <cstdint>
#include <memory>
#include "u2fd/fuzzers/fake_u2f_msg_handler.h"
#include "u2fd/fuzzers/fake_uhid_device.h"
#include "u2fd/hid_interface.h"
#include "u2fd/u2fhid.h"
namespace {
class FuzzerLoop : public brillo::Daemon {
public:
FuzzerLoop(const uint8_t* data, size_t size) : data_provider_(data, size) {}
FuzzerLoop(const FuzzerLoop&) = delete;
FuzzerLoop& operator=(const FuzzerLoop&) = delete;
~FuzzerLoop() override = default;
protected:
int OnInit() override {
int exit_code = brillo::Daemon::OnInit();
if (exit_code != EX_OK) {
return exit_code;
}
fake_u2f_msg_handler_ = std::make_unique<u2f::FakeU2fMessageHandler>();
auto fake_uhid_device = std::make_unique<u2f::FakeUHidDevice>();
fake_uhid_device_ = fake_uhid_device.get();
u2fhid_ = std::make_unique<u2f::U2fHid>(std::move(fake_uhid_device),
fake_u2f_msg_handler_.get());
ScheduleSendOutputReport();
return EX_OK;
}
private:
void ScheduleSendOutputReport() {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&FuzzerLoop::SendOutputReport, base::Unretained(this)));
}
void SendOutputReport() {
if (data_provider_.remaining_bytes() == 0) {
Quit();
return;
}
// Sending the output report to U2fHid::ProcessReport
fake_uhid_device_->SendOutputReport(
data_provider_.ConsumeRandomLengthString());
ScheduleSendOutputReport();
}
FuzzedDataProvider data_provider_;
u2f::FakeUHidDevice* fake_uhid_device_;
std::unique_ptr<u2f::FakeU2fMessageHandler> fake_u2f_msg_handler_;
std::unique_ptr<u2f::U2fHid> u2fhid_;
};
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzerLoop loop(data, size);
CHECK_EQ(loop.Run(), EX_OK);
return 0;
}