blob: 325b21984d45df7e517cf7f62e1d214812eae643 [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.
27 int RunInMinijail(const std::vector<std::string>& argv) override {
28 return 0;
29 }
30
31 DISALLOW_COPY_AND_ASSIGN(FakeFirewall);
32};
33
34} // namespace patchpanel
35
36struct Environment {
37 Environment() {
38 logging::SetMinLogLevel(logging::LOG_FATAL);
39 }
40};
41
42void FuzzAcceptRules(patchpanel::FakeFirewall& fake_firewall,
43 const uint8_t* data,
44 size_t size) {
45 FuzzedDataProvider data_provider(data, size);
46 while (data_provider.remaining_bytes() > 0) {
47 ModifyPortRuleRequest::Protocol proto = data_provider.ConsumeBool()
48 ? ModifyPortRuleRequest::TCP
49 : ModifyPortRuleRequest::UDP;
50 uint16_t port = data_provider.ConsumeIntegral<uint16_t>();
51 std::string iface = data_provider.ConsumeRandomLengthString(IFNAMSIZ - 1);
52 if (data_provider.ConsumeBool()) {
53 fake_firewall.AddAcceptRules(proto, port, iface);
54 } else {
55 fake_firewall.DeleteAcceptRules(proto, port, iface);
56 }
57 }
58}
59
60void FuzzForwardRules(patchpanel::FakeFirewall& fake_firewall,
61 const uint8_t* data,
62 size_t size) {
63 FuzzedDataProvider data_provider(data, size);
64 while (data_provider.remaining_bytes() > 0) {
65 ModifyPortRuleRequest::Protocol proto = data_provider.ConsumeBool()
66 ? ModifyPortRuleRequest::TCP
67 : ModifyPortRuleRequest::UDP;
68 uint16_t forwarded_port = data_provider.ConsumeIntegral<uint16_t>();
69 uint16_t dst_port = data_provider.ConsumeIntegral<uint16_t>();
70 struct in_addr input_ip_addr = {
71 .s_addr = data_provider.ConsumeIntegral<uint32_t>()};
72 struct in_addr dst_ip_addr = {
73 .s_addr = data_provider.ConsumeIntegral<uint32_t>()};
74 char input_buffer[INET_ADDRSTRLEN];
75 char dst_buffer[INET_ADDRSTRLEN];
76 memset(input_buffer, 0, INET_ADDRSTRLEN);
77 memset(dst_buffer, 0, INET_ADDRSTRLEN);
78 inet_ntop(AF_INET, &input_ip_addr, input_buffer, INET_ADDRSTRLEN);
79 inet_ntop(AF_INET, &dst_ip_addr, dst_buffer, INET_ADDRSTRLEN);
80 std::string input_ip = input_buffer;
81 std::string dst_ip = dst_buffer;
82 std::string iface = data_provider.ConsumeRandomLengthString(IFNAMSIZ - 1);
83 if (data_provider.ConsumeBool()) {
84 fake_firewall.AddIpv4ForwardRule(proto, input_ip, forwarded_port, iface,
85 dst_ip, dst_port);
86 } else {
87 fake_firewall.DeleteIpv4ForwardRule(proto, input_ip, forwarded_port,
88 iface, dst_ip, dst_port);
89 }
90 }
91}
92
93void FuzzLoopbackLockdownRules(patchpanel::FakeFirewall& fake_firewall,
94 const uint8_t* data,
95 size_t size) {
96 FuzzedDataProvider data_provider(data, size);
97 while (data_provider.remaining_bytes() > 0) {
98 ModifyPortRuleRequest::Protocol proto = data_provider.ConsumeBool()
99 ? ModifyPortRuleRequest::TCP
100 : ModifyPortRuleRequest::UDP;
101 uint16_t port = data_provider.ConsumeIntegral<uint16_t>();
102 if (data_provider.ConsumeBool()) {
103 fake_firewall.AddLoopbackLockdownRules(proto, port);
104 } else {
105 fake_firewall.DeleteLoopbackLockdownRules(proto, port);
106 }
107 }
108}
109
110extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
111 static Environment env;
112
113 patchpanel::FakeFirewall fake_firewall;
114
115 FuzzAcceptRules(fake_firewall, data, size);
116 FuzzForwardRules(fake_firewall, data, size);
117 FuzzLoopbackLockdownRules(fake_firewall, data, size);
118
119 return 0;
120}