blob: 7ffd6612e152de0000a6a4aa58aaf0dc3b3e03f2 [file] [log] [blame]
Hugo Benichib9b93fe2019-10-25 23:36:01 +09001// Copyright 2019 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 <net/if.h>
6
7#include <fuzzer/FuzzedDataProvider.h>
8#include <string>
9#include <vector>
10
Jason Jeremy Imanbb5f2f82020-08-30 19:02:19 +090011#include <base/at_exit.h>
Hugo Benichib9b93fe2019-10-25 23:36:01 +090012#include <base/bind.h>
Garrick Evans495dfc42020-02-14 07:20:57 +090013#include <base/bind_helpers.h>
Hugo Benichib9b93fe2019-10-25 23:36:01 +090014#include <base/logging.h>
15
Garrick Evans3388a032020-03-24 11:25:55 +090016#include "patchpanel/datapath.h"
Jason Jeremy Iman2096b512020-08-20 11:55:12 +090017#include "patchpanel/firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090018#include "patchpanel/minijailed_process_runner.h"
19#include "patchpanel/multicast_forwarder.h"
20#include "patchpanel/net_util.h"
Hugo Benichib66431f2020-12-10 17:07:12 +090021#include "patchpanel/subnet.h"
Hugo Benichib9b93fe2019-10-25 23:36:01 +090022
Garrick Evans3388a032020-03-24 11:25:55 +090023namespace patchpanel {
Hugo Benichib9b93fe2019-10-25 23:36:01 +090024
25// Always succeeds
26int ioctl_stub(int fd, unsigned long req, ...) {
27 return 0;
28}
29
30class RandomProcessRunner : public MinijailedProcessRunner {
31 public:
32 explicit RandomProcessRunner(FuzzedDataProvider* data_provider)
33 : data_provider_{data_provider} {}
Qijiang Fan6bc59e12020-11-11 02:51:06 +090034 RandomProcessRunner(const RandomProcessRunner&) = delete;
35 RandomProcessRunner& operator=(const RandomProcessRunner&) = delete;
Hugo Benichib9b93fe2019-10-25 23:36:01 +090036 ~RandomProcessRunner() = default;
37
38 int Run(const std::vector<std::string>& argv, bool log_failures) override {
39 return data_provider_->ConsumeBool();
40 }
41
Hugo Benichib5b44cc2020-12-11 11:01:02 +090042 int RunSync(const std::vector<std::string>& argv,
Hugo Benichib5b44cc2020-12-11 11:01:02 +090043 bool log_failures,
Jie Jiangc9a5cd52020-12-14 17:38:52 +090044 std::string* output) override {
Hugo Benichib5b44cc2020-12-11 11:01:02 +090045 return data_provider_->ConsumeBool();
46 }
47
Hugo Benichib9b93fe2019-10-25 23:36:01 +090048 private:
49 FuzzedDataProvider* data_provider_;
Hugo Benichib9b93fe2019-10-25 23:36:01 +090050};
51
52namespace {
53
Hugo Benichi7c342672020-09-08 09:18:14 +090054constexpr pid_t kTestPID = -2;
55
Hugo Benichib9b93fe2019-10-25 23:36:01 +090056class Environment {
57 public:
58 Environment() {
hschame6711302020-11-20 17:08:14 +090059 logging::SetMinLogLevel(logging::LOGGING_FATAL); // <- DISABLE LOGGING.
Hugo Benichib9b93fe2019-10-25 23:36:01 +090060 }
Jason Jeremy Imanbb5f2f82020-08-30 19:02:19 +090061 base::AtExitManager at_exit;
Hugo Benichib9b93fe2019-10-25 23:36:01 +090062};
63
64extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
Jason Jeremy Imanbb5f2f82020-08-30 19:02:19 +090065 static Environment env;
Hugo Benichib9b93fe2019-10-25 23:36:01 +090066
67 FuzzedDataProvider provider(data, size);
68 RandomProcessRunner runner(&provider);
Hugo Benichib9b93fe2019-10-25 23:36:01 +090069
70 while (provider.remaining_bytes() > 0) {
Hugo Benichi82ed5cf2020-09-08 21:30:22 +090071 uint32_t pid = provider.ConsumeIntegral<uint32_t>();
Hugo Benichi9ab5a052020-07-28 11:29:01 +090072 std::string netns_name = provider.ConsumeRandomLengthString(10);
Hugo Benichib9b93fe2019-10-25 23:36:01 +090073 std::string ifname = provider.ConsumeRandomLengthString(IFNAMSIZ - 1);
Hugo Benichi8d622b52020-08-13 15:24:12 +090074 std::string ifname2 = provider.ConsumeRandomLengthString(IFNAMSIZ - 1);
Hugo Benichib66431f2020-12-10 17:07:12 +090075 std::string ifname3 = provider.ConsumeRandomLengthString(IFNAMSIZ - 1);
Hugo Benichib9b93fe2019-10-25 23:36:01 +090076 std::string bridge = provider.ConsumeRandomLengthString(IFNAMSIZ - 1);
Garrick Evans495dfc42020-02-14 07:20:57 +090077 uint32_t addr = provider.ConsumeIntegral<uint32_t>();
78 std::string addr_str = IPv4AddressToString(addr);
79 uint32_t prefix_len = provider.ConsumeIntegralInRange<uint32_t>(0, 31);
80 Subnet subnet(provider.ConsumeIntegral<int32_t>(), prefix_len,
hschamee9e3a12020-02-03 16:34:28 +090081 base::DoNothing());
Hugo Benichib9b93fe2019-10-25 23:36:01 +090082 std::unique_ptr<SubnetAddress> subnet_addr = subnet.AllocateAtOffset(0);
83 MacAddress mac;
84 std::vector<uint8_t> bytes = provider.ConsumeBytes<uint8_t>(mac.size());
Hugo Benichiaf02c262021-01-26 10:24:10 +090085 std::copy(bytes.begin(), bytes.end(), mac.begin());
86 struct in6_addr ipv6_addr;
Hugo Benichie4307f52021-02-05 10:12:33 +090087 memset(&ipv6_addr, 0, sizeof(ipv6_addr));
Hugo Benichiaf02c262021-01-26 10:24:10 +090088 bytes = provider.ConsumeBytes<uint8_t>(sizeof(ipv6_addr.s6_addr));
89 std::copy(bytes.begin(), bytes.end(), ipv6_addr.s6_addr);
90 std::string ipv6_addr_str = IPv6AddressToString(ipv6_addr);
Hugo Benichib66431f2020-12-10 17:07:12 +090091 bool route_on_vpn = provider.ConsumeBool();
92
93 ConnectedNamespace nsinfo = {};
94 nsinfo.pid = kTestPID;
95 nsinfo.netns_name = netns_name;
96 nsinfo.source = TrafficSource::USER;
97 nsinfo.outbound_ifname = ifname;
98 nsinfo.route_on_vpn = route_on_vpn;
99 nsinfo.host_ifname = ifname2;
100 nsinfo.peer_ifname = ifname3;
101 nsinfo.peer_subnet =
102 std::make_unique<Subnet>(addr, prefix_len, base::DoNothing());
103 nsinfo.peer_mac_addr = mac;
Hugo Benichib9b93fe2019-10-25 23:36:01 +0900104
Hugo Benichiaf02c262021-01-26 10:24:10 +0900105 Firewall firewall;
106 Datapath datapath(&runner, &firewall, ioctl_stub);
Hugo Benichibf811c62020-09-07 17:30:45 +0900107 datapath.Start();
108 datapath.Stop();
Hugo Benichiaf02c262021-01-26 10:24:10 +0900109 datapath.NetnsAttachName(netns_name, kTestPID);
110 datapath.NetnsDeleteName(netns_name);
Garrick Evans495dfc42020-02-14 07:20:57 +0900111 datapath.AddBridge(ifname, addr, prefix_len);
Hugo Benichib9b93fe2019-10-25 23:36:01 +0900112 datapath.RemoveBridge(ifname);
Hugo Benichiaf02c262021-01-26 10:24:10 +0900113 datapath.AddToBridge(ifname, ifname2);
Hugo Benichib66431f2020-12-10 17:07:12 +0900114 datapath.StartRoutingDevice(ifname, ifname2, addr, TrafficSource::UNKNOWN,
115 route_on_vpn);
116 datapath.StopRoutingDevice(ifname, ifname2, addr, TrafficSource::UNKNOWN,
117 route_on_vpn);
118 datapath.StartRoutingNamespace(nsinfo);
119 datapath.StopRoutingNamespace(nsinfo);
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900120 datapath.ConnectVethPair(pid, netns_name, ifname, ifname2, mac, addr,
121 prefix_len, provider.ConsumeBool());
Hugo Benichib9b93fe2019-10-25 23:36:01 +0900122 datapath.RemoveInterface(ifname);
Garrick Evans4f9f5572019-11-26 10:25:16 +0900123 datapath.AddTAP(ifname, &mac, subnet_addr.get(), "");
Hugo Benichib9b93fe2019-10-25 23:36:01 +0900124 datapath.RemoveTAP(ifname);
Garrick Evans3d97a392020-02-21 15:24:37 +0900125 datapath.AddIPv4Route(provider.ConsumeIntegral<uint32_t>(),
126 provider.ConsumeIntegral<uint32_t>(),
127 provider.ConsumeIntegral<uint32_t>());
Hugo Benichiaf02c262021-01-26 10:24:10 +0900128 datapath.StartConnectionPinning(ifname);
129 datapath.StopConnectionPinning(ifname);
130 datapath.StartVpnRouting(ifname);
131 datapath.StopVpnRouting(ifname);
132 datapath.MaskInterfaceFlags(ifname, provider.ConsumeIntegral<uint16_t>(),
133 provider.ConsumeIntegral<uint16_t>());
134 datapath.AddIPv6Forwarding(ifname, ifname2);
135 datapath.RemoveIPv6Forwarding(ifname, ifname2);
136 datapath.AddIPv6HostRoute(ifname, ipv6_addr_str, prefix_len);
137 datapath.RemoveIPv6HostRoute(ifname, ipv6_addr_str, prefix_len);
138 datapath.AddIPv6Address(ifname, ipv6_addr_str);
139 datapath.RemoveIPv6Address(ifname, ipv6_addr_str);
Hugo Benichib9b93fe2019-10-25 23:36:01 +0900140 }
141
142 return 0;
143}
144
145} // namespace
Garrick Evans3388a032020-03-24 11:25:55 +0900146} // namespace patchpanel