blob: 5658e0853325910079589344dddacef3610de5a9 [file] [log] [blame]
Andreea Costinas65063152020-04-27 12:03:18 +02001// Copyright 2020 The Chromium OS 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 <stddef.h>
6#include <stdint.h>
7
8#include <sys/socket.h>
9#include <sys/types.h>
10
11#include <base/bind.h>
Qijiang Fan713061e2021-03-08 15:45:12 +090012#include <base/check.h>
Andreea Costinas65063152020-04-27 12:03:18 +020013#include <base/files/file_util.h>
14#include <base/logging.h>
Andreea Costinas65063152020-04-27 12:03:18 +020015#include <base/run_loop.h>
Qijiang Fan34014672020-07-20 16:05:38 +090016#include <base/task/single_thread_task_executor.h>
Andreea Costinasb715eef2020-05-26 09:14:32 +020017#include <base/test/test_mock_time_task_runner.h>
Andreea Costinas65063152020-04-27 12:03:18 +020018#include <brillo/message_loops/base_message_loop.h>
19#include <libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h>
20
21#include "bindings/worker_common.pb.h"
22#include "system-proxy/protobuf_util.h"
23#include "system-proxy/server_proxy.h"
24
25namespace {
26void NullClosure() {}
27} // namespace
28
29struct Environment {
30 Environment() {
hschame6711302020-11-20 17:08:14 +090031 logging::SetMinLogLevel(logging::LOGGING_FATAL); // Disable logging.
Andreea Costinas65063152020-04-27 12:03:18 +020032 }
33};
34
35// ServerProxy implementation that receives input from a given file descriptor,
36// instead of the default standard input file descriptor (STDIN_FILENO).
37class FakeServerProxy : public system_proxy::ServerProxy {
38 public:
Andreea Costinasb715eef2020-05-26 09:14:32 +020039 FakeServerProxy(base::ScopedFD stdin_fd, base::OnceClosure quit_task)
Andreea Costinas65063152020-04-27 12:03:18 +020040 : system_proxy::ServerProxy(base::BindOnce(&NullClosure)),
Andreea Costinasb715eef2020-05-26 09:14:32 +020041 stdin_fd_(std::move(stdin_fd)),
42 quit_task_(std::move(quit_task)) {}
Andreea Costinas65063152020-04-27 12:03:18 +020043 FakeServerProxy(const FakeServerProxy&) = delete;
44 FakeServerProxy& operator=(const FakeServerProxy&) = delete;
45 ~FakeServerProxy() override = default;
46
47 int GetStdinPipe() override { return stdin_fd_.get(); }
48
49 private:
Andreea Costinasb715eef2020-05-26 09:14:32 +020050 void HandleStdinReadable() override {
51 system_proxy::ServerProxy::HandleStdinReadable();
52 std::move(quit_task_).Run();
53 }
54
Andreea Costinas65063152020-04-27 12:03:18 +020055 base::ScopedFD stdin_fd_;
Andreea Costinasb715eef2020-05-26 09:14:32 +020056 base::OnceClosure quit_task_;
Andreea Costinas65063152020-04-27 12:03:18 +020057};
58
Andreea Costinasb715eef2020-05-26 09:14:32 +020059DEFINE_PROTO_FUZZER(const system_proxy::worker::WorkerConfigs& configs) {
Andreea Costinas65063152020-04-27 12:03:18 +020060 static Environment env;
61
62 // Mock main task runner
Qijiang Fan34014672020-07-20 16:05:38 +090063 base::SingleThreadTaskExecutor task_executor(base::MessagePumpType::IO);
64 brillo::BaseMessageLoop brillo_loop(task_executor.task_runner());
Andreea Costinas65063152020-04-27 12:03:18 +020065 brillo_loop.SetAsCurrent();
Andreea Costinasb715eef2020-05-26 09:14:32 +020066 base::RunLoop run_loop;
Andreea Costinas65063152020-04-27 12:03:18 +020067
68 int fds[2];
69 CHECK(base::CreateLocalNonBlockingPipe(fds));
70 base::ScopedFD stdin_read_fd(fds[0]);
71 base::ScopedFD stdin_write_fd(fds[1]);
72
Andreea Costinasb715eef2020-05-26 09:14:32 +020073 auto server = std::make_unique<FakeServerProxy>(std::move(stdin_read_fd),
74 run_loop.QuitClosure());
75 server->Init();
Andreea Costinas65063152020-04-27 12:03:18 +020076 // Send the config to the worker's stdin input.
Andreea Costinasb715eef2020-05-26 09:14:32 +020077 system_proxy::WriteProtobuf(stdin_write_fd.get(), configs);
78
79 run_loop.Run();
Andreea Costinas65063152020-04-27 12:03:18 +020080}