Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: net/dns/fuzzed_host_resolver.cc

Issue 1946793002: net: Add fuzzer for HostResolverImpl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove port 0 check Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/dns/fuzzed_host_resolver.h ('k') | net/dns/host_resolver_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium 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/dns/fuzzed_host_resolver.h"
6
7 #include <stdint.h>
8
9 #include <limits>
10 #include <string>
11
12 #include "base/bind.h"
13 #include "base/logging.h"
14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/threading/thread_task_runner_handle.h"
18 #include "net/base/address_list.h"
19 #include "net/base/fuzzed_data_provider.h"
20 #include "net/base/ip_address.h"
21 #include "net/base/ip_endpoint.h"
22 #include "net/base/net_errors.h"
23 #include "net/dns/dns_client.h"
24 #include "net/dns/dns_config_service.h"
25 #include "net/dns/dns_hosts.h"
26
27 namespace net {
28
29 namespace {
30
31 // Returns a fuzzed non-zero port number.
32 uint16_t FuzzPort(FuzzedDataProvider* data_provider) {
33 return data_provider->ConsumeUint16();
34 }
35
36 // Returns a fuzzed IPv4 address. Can return invalid / reserved addresses.
37 IPAddress FuzzIPv4Address(FuzzedDataProvider* data_provider) {
38 return IPAddress(data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
39 data_provider->ConsumeUint8(),
40 data_provider->ConsumeUint8());
41 }
42
43 // Returns a fuzzed IPv6 address. Can return invalid / reserved addresses.
44 IPAddress FuzzIPv6Address(FuzzedDataProvider* data_provider) {
45 return IPAddress(data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
46 data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
47 data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
48 data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
49 data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
50 data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
51 data_provider->ConsumeUint8(), data_provider->ConsumeUint8(),
52 data_provider->ConsumeUint8(),
53 data_provider->ConsumeUint8());
54 }
55
56 // Returns a fuzzed address, which can be either IPv4 or IPv6. Can return
57 // invalid / reserved addresses.
58 IPAddress FuzzIPAddress(FuzzedDataProvider* data_provider) {
59 if (data_provider->ConsumeBool())
60 return FuzzIPv4Address(data_provider);
61 return FuzzIPv6Address(data_provider);
62 }
63
64 // HostResolverProc that returns a random set of results, and can succeed or
65 // fail. Must only be run on the thread it's created on.
66 class FuzzedHostResolverProc : public HostResolverProc {
67 public:
68 // Can safely be used after the destruction of |data_provider|. This can
69 // happen if a request is issued but the code never waits for the result
70 // before the test ends.
71 explicit FuzzedHostResolverProc(
72 base::WeakPtr<FuzzedDataProvider> data_provider)
73 : HostResolverProc(nullptr),
74 data_provider_(data_provider),
75 network_task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
76
77 int Resolve(const std::string& host,
78 AddressFamily address_family,
79 HostResolverFlags host_resolver_flags,
80 AddressList* addrlist,
81 int* os_error) override {
82 DCHECK(network_task_runner_->BelongsToCurrentThread());
83
84 if (os_error)
85 *os_error = 0;
86
87 // If the data provider is no longer avaiable, just fail. The HostResolver
88 // has already been deleted by this point, anyways.
89 if (!data_provider_)
90 return ERR_FAILED;
91
92 AddressList result;
93
94 // Put IPv6 addresses before IPv4 ones. This code doesn't sort addresses
95 // correctly, but when sorted according to spec, IPv6 addresses are
96 // generally before IPv4 ones.
97 if (address_family == ADDRESS_FAMILY_UNSPECIFIED ||
98 address_family == ADDRESS_FAMILY_IPV6) {
99 size_t num_ipv6_addresses = data_provider_->ConsumeUint8();
100 for (size_t i = 0; i < num_ipv6_addresses; ++i) {
101 result.push_back(
102 net::IPEndPoint(FuzzIPv6Address(data_provider_.get()), 0));
103 }
104 }
105
106 if (address_family == ADDRESS_FAMILY_UNSPECIFIED ||
107 address_family == ADDRESS_FAMILY_IPV4) {
108 size_t num_ipv4_addresses = data_provider_->ConsumeUint8();
109 for (size_t i = 0; i < num_ipv4_addresses; ++i) {
110 result.push_back(
111 net::IPEndPoint(FuzzIPv4Address(data_provider_.get()), 0));
112 }
113 }
114
115 if (result.empty())
116 return ERR_NAME_NOT_RESOLVED;
117
118 if (host_resolver_flags & HOST_RESOLVER_CANONNAME) {
119 // Don't bother to fuzz this - almost nothing cares.
120 result.set_canonical_name("foo.com");
121 }
122
123 *addrlist = result;
124 return OK;
125 }
126
127 private:
128 ~FuzzedHostResolverProc() override {}
129
130 base::WeakPtr<FuzzedDataProvider> data_provider_;
131
132 // Just used for thread-safety checks.
133 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
134
135 DISALLOW_COPY_AND_ASSIGN(FuzzedHostResolverProc);
136 };
137
138 } // namespace
139
140 FuzzedHostResolver::FuzzedHostResolver(const Options& options,
141 NetLog* net_log,
142 FuzzedDataProvider* data_provider)
143 : HostResolverImpl(options, net_log, base::ThreadTaskRunnerHandle::Get()),
144 data_provider_(data_provider),
145 socket_factory_(data_provider),
146 is_ipv6_reachable_(data_provider->ConsumeBool()),
147 net_log_(net_log),
148 data_provider_weak_factory_(data_provider) {
149 HostResolverImpl::ProcTaskParams proc_task_params(
150 new FuzzedHostResolverProc(data_provider_weak_factory_.GetWeakPtr()),
151 // Retries are only used when the original request hangs, which this class
152 // currently can't simulate.
153 0 /* max_retry_attempts */);
154 set_proc_params_for_test(proc_task_params);
155 }
156
157 FuzzedHostResolver::~FuzzedHostResolver() {}
158
159 void FuzzedHostResolver::SetDnsClientEnabled(bool enabled) {
160 if (!enabled) {
161 HostResolverImpl::SetDnsClientEnabled(false);
162 return;
163 }
164
165 // Fuzz DNS configuration.
166
167 DnsConfig config;
168
169 // Fuzz name servers.
170 uint32_t num_nameservers = data_provider_->ConsumeUint32InRange(0, 4);
171 for (uint32_t i = 0; i < num_nameservers; ++i) {
172 config.nameservers.push_back(
173 IPEndPoint(FuzzIPAddress(data_provider_), FuzzPort(data_provider_)));
174 }
175
176 // Fuzz suffix search list. Each case deliberately falls through.
177 switch (data_provider_->ConsumeUint32InRange(0, 3)) {
178 case 3:
179 config.search.push_back("foo.com");
180 case 2:
181 config.search.push_back("bar");
182 case 1:
183 config.search.push_back("com");
184 default:
185 break;
186 }
187
188 net::DnsHosts hosts;
189 // Fuzz hosts file.
190 uint8_t num_hosts_entries = data_provider_->ConsumeUint8();
191 for (uint8_t i = 0; i < num_hosts_entries; ++i) {
192 const char* kHostnames[] = {"foo", "foo.com", "a.foo.com",
193 "bar", "localhost", "localhost6"};
194 const char* hostname = data_provider_->PickValueInArray(kHostnames);
195 net::IPAddress address = FuzzIPAddress(data_provider_);
196 config.hosts[net::DnsHostsKey(hostname, net::GetAddressFamily(address))] =
197 address;
198 }
199
200 config.unhandled_options = data_provider_->ConsumeBool();
201 config.append_to_multi_label_name = data_provider_->ConsumeBool();
202 config.randomize_ports = data_provider_->ConsumeBool();
203 config.ndots = data_provider_->ConsumeInt32InRange(0, 3);
204 config.attempts = data_provider_->ConsumeInt32InRange(1, 3);
205
206 // Timeouts don't really work for fuzzing. Even a timeout of 0 milliseconds
207 // will be increased after the first timeout, resulting in inconsistent
208 // behavior.
209 config.timeout = base::TimeDelta::FromDays(10);
210
211 config.rotate = data_provider_->ConsumeBool();
212
213 // Doesn't currently seem to do anything.
214 config.edns0 = false;
215
216 config.use_local_ipv6 = data_provider_->ConsumeBool();
217
218 std::unique_ptr<DnsClient> dns_client = DnsClient::CreateClientForTesting(
219 net_log_, &socket_factory_,
220 base::Bind(&FuzzedDataProvider::ConsumeInt32InRange,
221 base::Unretained(data_provider_)));
222 dns_client->SetConfig(config);
223 SetDnsClient(std::move(dns_client));
224 }
225
226 bool FuzzedHostResolver::IsIPv6Reachable(const BoundNetLog& net_log) {
227 return is_ipv6_reachable_;
228 }
229
230 void FuzzedHostResolver::RunLoopbackProbeJob() {
231 SetHaveOnlyLoopbackAddresses(data_provider_->ConsumeBool());
232 }
233
234 } // namespace net
OLDNEW
« no previous file with comments | « net/dns/fuzzed_host_resolver.h ('k') | net/dns/host_resolver_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698