blob: 64d7081475c27a64499bd8cb35a3d530716f870d [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;
Qijiang Fan6bc59e12020-11-11 02:51:06 +090023 FakeFirewall(const FakeFirewall&) = delete;
24 FakeFirewall& operator=(const FakeFirewall&) = delete;
25
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090026 ~FakeFirewall() = default;
27
28 private:
29 // The fake's implementation always succeeds.
Tom Hughes249adef2020-08-24 18:21:52 -070030 int RunInMinijail(const std::vector<std::string>& argv) override { return 0; }
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090031};
32
33} // namespace patchpanel
34
35struct Environment {
hschame6711302020-11-20 17:08:14 +090036 Environment() { logging::SetMinLogLevel(logging::LOGGING_FATAL); }
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090037};
38
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070039void FuzzAcceptRules(patchpanel::FakeFirewall* fake_firewall,
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090040 const uint8_t* data,
41 size_t size) {
42 FuzzedDataProvider data_provider(data, size);
43 while (data_provider.remaining_bytes() > 0) {
44 ModifyPortRuleRequest::Protocol proto = data_provider.ConsumeBool()
45 ? ModifyPortRuleRequest::TCP
46 : ModifyPortRuleRequest::UDP;
47 uint16_t port = data_provider.ConsumeIntegral<uint16_t>();
48 std::string iface = data_provider.ConsumeRandomLengthString(IFNAMSIZ - 1);
49 if (data_provider.ConsumeBool()) {
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070050 fake_firewall->AddAcceptRules(proto, port, iface);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090051 } else {
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070052 fake_firewall->DeleteAcceptRules(proto, port, iface);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090053 }
54 }
55}
56
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070057void FuzzForwardRules(patchpanel::FakeFirewall* fake_firewall,
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090058 const uint8_t* data,
59 size_t size) {
60 FuzzedDataProvider data_provider(data, size);
61 while (data_provider.remaining_bytes() > 0) {
62 ModifyPortRuleRequest::Protocol proto = data_provider.ConsumeBool()
63 ? ModifyPortRuleRequest::TCP
64 : ModifyPortRuleRequest::UDP;
65 uint16_t forwarded_port = data_provider.ConsumeIntegral<uint16_t>();
66 uint16_t dst_port = data_provider.ConsumeIntegral<uint16_t>();
67 struct in_addr input_ip_addr = {
68 .s_addr = data_provider.ConsumeIntegral<uint32_t>()};
69 struct in_addr dst_ip_addr = {
70 .s_addr = data_provider.ConsumeIntegral<uint32_t>()};
71 char input_buffer[INET_ADDRSTRLEN];
72 char dst_buffer[INET_ADDRSTRLEN];
73 memset(input_buffer, 0, INET_ADDRSTRLEN);
74 memset(dst_buffer, 0, INET_ADDRSTRLEN);
75 inet_ntop(AF_INET, &input_ip_addr, input_buffer, INET_ADDRSTRLEN);
76 inet_ntop(AF_INET, &dst_ip_addr, dst_buffer, INET_ADDRSTRLEN);
77 std::string input_ip = input_buffer;
78 std::string dst_ip = dst_buffer;
79 std::string iface = data_provider.ConsumeRandomLengthString(IFNAMSIZ - 1);
80 if (data_provider.ConsumeBool()) {
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070081 fake_firewall->AddIpv4ForwardRule(proto, input_ip, forwarded_port, iface,
82 dst_ip, dst_port);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090083 } else {
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070084 fake_firewall->DeleteIpv4ForwardRule(proto, input_ip, forwarded_port,
85 iface, dst_ip, dst_port);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090086 }
87 }
88}
89
Tom Hughes0f6ba9d2020-09-08 11:58:23 -070090void FuzzLoopbackLockdownRules(patchpanel::FakeFirewall* fake_firewall,
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +090091 const uint8_t* data,
92 size_t size) {
93 FuzzedDataProvider data_provider(data, size);
94 while (data_provider.remaining_bytes() > 0) {
95 ModifyPortRuleRequest::Protocol proto = data_provider.ConsumeBool()
96 ? ModifyPortRuleRequest::TCP
97 : ModifyPortRuleRequest::UDP;
98 uint16_t port = data_provider.ConsumeIntegral<uint16_t>();
99 if (data_provider.ConsumeBool()) {
Tom Hughes0f6ba9d2020-09-08 11:58:23 -0700100 fake_firewall->AddLoopbackLockdownRules(proto, port);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +0900101 } else {
Tom Hughes0f6ba9d2020-09-08 11:58:23 -0700102 fake_firewall->DeleteLoopbackLockdownRules(proto, port);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +0900103 }
104 }
105}
106
107extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
108 static Environment env;
109
110 patchpanel::FakeFirewall fake_firewall;
111
Tom Hughes0f6ba9d2020-09-08 11:58:23 -0700112 FuzzAcceptRules(&fake_firewall, data, size);
113 FuzzForwardRules(&fake_firewall, data, size);
114 FuzzLoopbackLockdownRules(&fake_firewall, data, size);
Jason Jeremy Iman54c046f2020-06-23 23:12:00 +0900115
116 return 0;
117}