blob: 7962b632db43e9075916a38fd2ca98ae2412d1f0 [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>
12#include <base/files/file_util.h>
13#include <base/logging.h>
Andreea Costinas65063152020-04-27 12:03:18 +020014#include <base/run_loop.h>
Qijiang Fan34014672020-07-20 16:05:38 +090015#include <base/task/single_thread_task_executor.h>
Andreea Costinasb715eef2020-05-26 09:14:32 +020016#include <base/test/test_mock_time_task_runner.h>
Andreea Costinas65063152020-04-27 12:03:18 +020017#include <brillo/message_loops/base_message_loop.h>
18#include <libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h>
19
20#include "bindings/worker_common.pb.h"
21#include "system-proxy/protobuf_util.h"
22#include "system-proxy/server_proxy.h"
23
24namespace {
25void NullClosure() {}
26} // namespace
27
28struct Environment {
29 Environment() {
hschame6711302020-11-20 17:08:14 +090030 logging::SetMinLogLevel(logging::LOGGING_FATAL); // Disable logging.
Andreea Costinas65063152020-04-27 12:03:18 +020031 }
32};
33
34// ServerProxy implementation that receives input from a given file descriptor,
35// instead of the default standard input file descriptor (STDIN_FILENO).
36class FakeServerProxy : public system_proxy::ServerProxy {
37 public:
Andreea Costinasb715eef2020-05-26 09:14:32 +020038 FakeServerProxy(base::ScopedFD stdin_fd, base::OnceClosure quit_task)
Andreea Costinas65063152020-04-27 12:03:18 +020039 : system_proxy::ServerProxy(base::BindOnce(&NullClosure)),
Andreea Costinasb715eef2020-05-26 09:14:32 +020040 stdin_fd_(std::move(stdin_fd)),
41 quit_task_(std::move(quit_task)) {}
Andreea Costinas65063152020-04-27 12:03:18 +020042 FakeServerProxy(const FakeServerProxy&) = delete;
43 FakeServerProxy& operator=(const FakeServerProxy&) = delete;
44 ~FakeServerProxy() override = default;
45
46 int GetStdinPipe() override { return stdin_fd_.get(); }
47
48 private:
Andreea Costinasb715eef2020-05-26 09:14:32 +020049 void HandleStdinReadable() override {
50 system_proxy::ServerProxy::HandleStdinReadable();
51 std::move(quit_task_).Run();
52 }
53
Andreea Costinas65063152020-04-27 12:03:18 +020054 base::ScopedFD stdin_fd_;
Andreea Costinasb715eef2020-05-26 09:14:32 +020055 base::OnceClosure quit_task_;
Andreea Costinas65063152020-04-27 12:03:18 +020056};
57
Andreea Costinasb715eef2020-05-26 09:14:32 +020058DEFINE_PROTO_FUZZER(const system_proxy::worker::WorkerConfigs& configs) {
Andreea Costinas65063152020-04-27 12:03:18 +020059 static Environment env;
60
61 // Mock main task runner
Qijiang Fan34014672020-07-20 16:05:38 +090062 base::SingleThreadTaskExecutor task_executor(base::MessagePumpType::IO);
63 brillo::BaseMessageLoop brillo_loop(task_executor.task_runner());
Andreea Costinas65063152020-04-27 12:03:18 +020064 brillo_loop.SetAsCurrent();
Andreea Costinasb715eef2020-05-26 09:14:32 +020065 base::RunLoop run_loop;
Andreea Costinas65063152020-04-27 12:03:18 +020066
67 int fds[2];
68 CHECK(base::CreateLocalNonBlockingPipe(fds));
69 base::ScopedFD stdin_read_fd(fds[0]);
70 base::ScopedFD stdin_write_fd(fds[1]);
71
Andreea Costinasb715eef2020-05-26 09:14:32 +020072 auto server = std::make_unique<FakeServerProxy>(std::move(stdin_read_fd),
73 run_loop.QuitClosure());
74 server->Init();
Andreea Costinas65063152020-04-27 12:03:18 +020075 // Send the config to the worker's stdin input.
Andreea Costinasb715eef2020-05-26 09:14:32 +020076 system_proxy::WriteProtobuf(stdin_write_fd.get(), configs);
77
78 run_loop.Run();
Andreea Costinas65063152020-04-27 12:03:18 +020079}