blob: d2833d5f510f316b4c04ddd78d77c79feefd7a89 [file] [log] [blame]
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +09001// Copyright 2018 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 <arpa/inet.h>
6#include <net/if.h>
7
8#include <fuzzer/FuzzedDataProvider.h>
9#include <set>
10
11#include "base/logging.h"
12
13#include "patchpanel/firewall.h"
14
15using patchpanel::ModifyPortRuleRequest;
16using Protocol = patchpanel::ModifyPortRuleRequest::Protocol;
17
18namespace patchpanel {
19
20class FakeFirewall : public Firewall {
21 public:
22 FakeFirewall() = default;
23 ~FakeFirewall() = default;
24
25 private:
26 // The fake's implementation always succeeds.
Tom Hughes249adef2020-08-24 18:21:52 -070027 int RunInMinijail(const std::vector<std::string>& argv) override { return 0; }
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090028
29 DISALLOW_COPY_AND_ASSIGN(FakeFirewall);
30};
31
32} // namespace patchpanel
33
34struct Environment {
Tom Hughes249adef2020-08-24 18:21:52 -070035 Environment() { logging::SetMinLogLevel(logging::LOG_FATAL); }
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090036};
37
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070038void FuzzAcceptRules(patchpanel::FakeFirewall* fake_firewall,
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090039 const uint8_t* data,
40 size_t size) {
41 FuzzedDataProvider data_provider(data, size);
42 while (data_provider.remaining_bytes() > 0) {
43 ModifyPortRuleRequest::Protocol proto = data_provider.ConsumeBool()
44 ? ModifyPortRuleRequest::TCP
45 : ModifyPortRuleRequest::UDP;
46 uint16_t port = data_provider.ConsumeIntegral<uint16_t>();
47 std::string iface = data_provider.ConsumeRandomLengthString(IFNAMSIZ - 1);
48 if (data_provider.ConsumeBool()) {
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070049 fake_firewall->AddAcceptRules(proto, port, iface);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090050 } else {
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070051 fake_firewall->DeleteAcceptRules(proto, port, iface);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090052 }
53 }
54}
55
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070056void FuzzForwardRules(patchpanel::FakeFirewall* fake_firewall,
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090057 const uint8_t* data,
58 size_t size) {
59 FuzzedDataProvider data_provider(data, size);
60 while (data_provider.remaining_bytes() > 0) {
61 ModifyPortRuleRequest::Protocol proto = data_provider.ConsumeBool()
62 ? ModifyPortRuleRequest::TCP
63 : ModifyPortRuleRequest::UDP;
64 uint16_t forwarded_port = data_provider.ConsumeIntegral<uint16_t>();
65 uint16_t dst_port = data_provider.ConsumeIntegral<uint16_t>();
66 struct in_addr input_ip_addr = {
67 .s_addr = data_provider.ConsumeIntegral<uint32_t>()};
68 struct in_addr dst_ip_addr = {
69 .s_addr = data_provider.ConsumeIntegral<uint32_t>()};
70 char input_buffer[INET_ADDRSTRLEN];
71 char dst_buffer[INET_ADDRSTRLEN];
72 memset(input_buffer, 0, INET_ADDRSTRLEN);
73 memset(dst_buffer, 0, INET_ADDRSTRLEN);
74 inet_ntop(AF_INET, &input_ip_addr, input_buffer, INET_ADDRSTRLEN);
75 inet_ntop(AF_INET, &dst_ip_addr, dst_buffer, INET_ADDRSTRLEN);
76 std::string input_ip = input_buffer;
77 std::string dst_ip = dst_buffer;
78 std::string iface = data_provider.ConsumeRandomLengthString(IFNAMSIZ - 1);
79 if (data_provider.ConsumeBool()) {
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070080 fake_firewall->AddIpv4ForwardRule(proto, input_ip, forwarded_port, iface,
81 dst_ip, dst_port);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090082 } else {
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070083 fake_firewall->DeleteIpv4ForwardRule(proto, input_ip, forwarded_port,
84 iface, dst_ip, dst_port);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090085 }
86 }
87}
88
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070089void FuzzLoopbackLockdownRules(patchpanel::FakeFirewall* fake_firewall,
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090090 const uint8_t* data,
91 size_t size) {
92 FuzzedDataProvider data_provider(data, size);
93 while (data_provider.remaining_bytes() > 0) {
94 ModifyPortRuleRequest::Protocol proto = data_provider.ConsumeBool()
95 ? ModifyPortRuleRequest::TCP
96 : ModifyPortRuleRequest::UDP;
97 uint16_t port = data_provider.ConsumeIntegral<uint16_t>();
98 if (data_provider.ConsumeBool()) {
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070099 fake_firewall->AddLoopbackLockdownRules(proto, port);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +0900100 } else {
Tom Hughes0f6ba9d2020-09-08 11:58:23 -0700101 fake_firewall->DeleteLoopbackLockdownRules(proto, port);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +0900102 }
103 }
104}
105
106extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
107 static Environment env;
108
109 patchpanel::FakeFirewall fake_firewall;
110
Tom Hughes0f6ba9d2020-09-08 11:58:23 -0700111 FuzzAcceptRules(&fake_firewall, data, size);
112 FuzzForwardRules(&fake_firewall, data, size);
113 FuzzLoopbackLockdownRules(&fake_firewall, data, size);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +0900114
115 return 0;
116}