blob: d8f85f158fea7be2715d12b4da536762c1796804 [file] [log] [blame]
// Copyright 2018 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <arpa/inet.h>
#include <net/if.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <set>
#include <string>
#include <vector>
#include <base/logging.h>
#include "patchpanel/fake_process_runner.h"
#include "patchpanel/firewall.h"
using patchpanel::ModifyPortRuleRequest;
using Protocol = patchpanel::ModifyPortRuleRequest::Protocol;
namespace patchpanel {
namespace {
net_base::IPv4Address ConsumeIPv4Address(FuzzedDataProvider& provider) {
const auto bytes =
provider.ConsumeBytes<uint8_t>(net_base::IPv4Address::kAddressLength);
return net_base::IPv4Address::CreateFromBytes(bytes).value_or(
net_base::IPv4Address());
}
struct Environment {
Environment() { logging::SetMinLogLevel(logging::LOGGING_FATAL); }
};
void FuzzAcceptRules(patchpanel::Firewall* firewall,
const uint8_t* data,
size_t size) {
FuzzedDataProvider data_provider(data, size);
while (data_provider.remaining_bytes() > 0) {
ModifyPortRuleRequest::Protocol proto = data_provider.ConsumeBool()
? ModifyPortRuleRequest::TCP
: ModifyPortRuleRequest::UDP;
uint16_t port = data_provider.ConsumeIntegral<uint16_t>();
std::string iface = data_provider.ConsumeRandomLengthString(IFNAMSIZ - 1);
if (data_provider.ConsumeBool()) {
firewall->AddAcceptRules(proto, port, iface);
} else {
firewall->DeleteAcceptRules(proto, port, iface);
}
}
}
void FuzzForwardRules(patchpanel::Firewall* firewall,
const uint8_t* data,
size_t size) {
FuzzedDataProvider data_provider(data, size);
while (data_provider.remaining_bytes() > 0) {
ModifyPortRuleRequest::Protocol proto = data_provider.ConsumeBool()
? ModifyPortRuleRequest::TCP
: ModifyPortRuleRequest::UDP;
uint16_t forwarded_port = data_provider.ConsumeIntegral<uint16_t>();
uint16_t dst_port = data_provider.ConsumeIntegral<uint16_t>();
const auto input_ip = ConsumeIPv4Address(data_provider);
const auto dst_ip = ConsumeIPv4Address(data_provider);
std::string iface = data_provider.ConsumeRandomLengthString(IFNAMSIZ - 1);
if (data_provider.ConsumeBool()) {
firewall->AddIpv4ForwardRule(proto, input_ip, forwarded_port, iface,
dst_ip, dst_port);
} else {
firewall->DeleteIpv4ForwardRule(proto, input_ip, forwarded_port, iface,
dst_ip, dst_port);
}
}
}
void FuzzLoopbackLockdownRules(patchpanel::Firewall* firewall,
const uint8_t* data,
size_t size) {
FuzzedDataProvider data_provider(data, size);
while (data_provider.remaining_bytes() > 0) {
ModifyPortRuleRequest::Protocol proto = data_provider.ConsumeBool()
? ModifyPortRuleRequest::TCP
: ModifyPortRuleRequest::UDP;
uint16_t port = data_provider.ConsumeIntegral<uint16_t>();
if (data_provider.ConsumeBool()) {
firewall->AddLoopbackLockdownRules(proto, port);
} else {
firewall->DeleteLoopbackLockdownRules(proto, port);
}
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
static Environment env;
auto process_runner = new patchpanel::FakeProcessRunner();
patchpanel::Firewall firewall(process_runner);
FuzzAcceptRules(&firewall, data, size);
FuzzForwardRules(&firewall, data, size);
FuzzLoopbackLockdownRules(&firewall, data, size);
return 0;
}
} // namespace
} // namespace patchpanel