1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include <fuzzer/FuzzedDataProvider.h>
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <algorithm>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
11*6777b538SAndroid Build Coastguard Worker #include "net/base/host_port_pair.h"
12*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/base/request_priority.h"
14*6777b538SAndroid Build Coastguard Worker #include "net/base/session_usage.h"
15*6777b538SAndroid Build Coastguard Worker #include "net/cert/x509_certificate.h"
16*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/secure_dns_policy.h"
17*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log.h"
18*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_source.h"
19*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log.h"
20*6777b538SAndroid Build Coastguard Worker #include "net/socket/fuzzed_socket_factory.h"
21*6777b538SAndroid Build Coastguard Worker #include "net/socket/socket_tag.h"
22*6777b538SAndroid Build Coastguard Worker #include "net/socket/socket_test_util.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/socket/ssl_client_socket.h"
24*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_test_util_common.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/ssl/ssl_config.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
27*6777b538SAndroid Build Coastguard Worker
28*6777b538SAndroid Build Coastguard Worker namespace {
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard Worker const uint8_t kCertData[] = {
31*6777b538SAndroid Build Coastguard Worker #include "net/data/ssl/certificates/spdy_pooling.inc"
32*6777b538SAndroid Build Coastguard Worker };
33*6777b538SAndroid Build Coastguard Worker
34*6777b538SAndroid Build Coastguard Worker class FuzzerDelegate : public net::SpdyStream::Delegate {
35*6777b538SAndroid Build Coastguard Worker public:
FuzzerDelegate(base::OnceClosure done_closure)36*6777b538SAndroid Build Coastguard Worker explicit FuzzerDelegate(base::OnceClosure done_closure)
37*6777b538SAndroid Build Coastguard Worker : done_closure_(std::move(done_closure)) {}
38*6777b538SAndroid Build Coastguard Worker
39*6777b538SAndroid Build Coastguard Worker FuzzerDelegate(const FuzzerDelegate&) = delete;
40*6777b538SAndroid Build Coastguard Worker FuzzerDelegate& operator=(const FuzzerDelegate&) = delete;
41*6777b538SAndroid Build Coastguard Worker
OnHeadersSent()42*6777b538SAndroid Build Coastguard Worker void OnHeadersSent() override {}
OnEarlyHintsReceived(const spdy::Http2HeaderBlock & headers)43*6777b538SAndroid Build Coastguard Worker void OnEarlyHintsReceived(const spdy::Http2HeaderBlock& headers) override {}
OnHeadersReceived(const spdy::Http2HeaderBlock & response_headers)44*6777b538SAndroid Build Coastguard Worker void OnHeadersReceived(
45*6777b538SAndroid Build Coastguard Worker const spdy::Http2HeaderBlock& response_headers) override {}
OnDataReceived(std::unique_ptr<net::SpdyBuffer> buffer)46*6777b538SAndroid Build Coastguard Worker void OnDataReceived(std::unique_ptr<net::SpdyBuffer> buffer) override {}
OnDataSent()47*6777b538SAndroid Build Coastguard Worker void OnDataSent() override {}
OnTrailers(const spdy::Http2HeaderBlock & trailers)48*6777b538SAndroid Build Coastguard Worker void OnTrailers(const spdy::Http2HeaderBlock& trailers) override {}
OnClose(int status)49*6777b538SAndroid Build Coastguard Worker void OnClose(int status) override { std::move(done_closure_).Run(); }
CanGreaseFrameType() const50*6777b538SAndroid Build Coastguard Worker bool CanGreaseFrameType() const override { return false; }
51*6777b538SAndroid Build Coastguard Worker
source_dependency() const52*6777b538SAndroid Build Coastguard Worker net::NetLogSource source_dependency() const override {
53*6777b538SAndroid Build Coastguard Worker return net::NetLogSource();
54*6777b538SAndroid Build Coastguard Worker }
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker private:
57*6777b538SAndroid Build Coastguard Worker base::OnceClosure done_closure_;
58*6777b538SAndroid Build Coastguard Worker };
59*6777b538SAndroid Build Coastguard Worker
60*6777b538SAndroid Build Coastguard Worker } // namespace
61*6777b538SAndroid Build Coastguard Worker
62*6777b538SAndroid Build Coastguard Worker namespace net {
63*6777b538SAndroid Build Coastguard Worker
64*6777b538SAndroid Build Coastguard Worker namespace {
65*6777b538SAndroid Build Coastguard Worker
66*6777b538SAndroid Build Coastguard Worker class FuzzedSocketFactoryWithMockSSLData : public FuzzedSocketFactory {
67*6777b538SAndroid Build Coastguard Worker public:
68*6777b538SAndroid Build Coastguard Worker explicit FuzzedSocketFactoryWithMockSSLData(
69*6777b538SAndroid Build Coastguard Worker FuzzedDataProvider* data_provider);
70*6777b538SAndroid Build Coastguard Worker
71*6777b538SAndroid Build Coastguard Worker void AddSSLSocketDataProvider(SSLSocketDataProvider* socket);
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SSLClientSocket> CreateSSLClientSocket(
74*6777b538SAndroid Build Coastguard Worker SSLClientContext* context,
75*6777b538SAndroid Build Coastguard Worker std::unique_ptr<StreamSocket> nested_socket,
76*6777b538SAndroid Build Coastguard Worker const HostPortPair& host_and_port,
77*6777b538SAndroid Build Coastguard Worker const SSLConfig& ssl_config) override;
78*6777b538SAndroid Build Coastguard Worker
79*6777b538SAndroid Build Coastguard Worker private:
80*6777b538SAndroid Build Coastguard Worker SocketDataProviderArray<SSLSocketDataProvider> mock_ssl_data_;
81*6777b538SAndroid Build Coastguard Worker };
82*6777b538SAndroid Build Coastguard Worker
FuzzedSocketFactoryWithMockSSLData(FuzzedDataProvider * data_provider)83*6777b538SAndroid Build Coastguard Worker FuzzedSocketFactoryWithMockSSLData::FuzzedSocketFactoryWithMockSSLData(
84*6777b538SAndroid Build Coastguard Worker FuzzedDataProvider* data_provider)
85*6777b538SAndroid Build Coastguard Worker : FuzzedSocketFactory(data_provider) {}
86*6777b538SAndroid Build Coastguard Worker
AddSSLSocketDataProvider(SSLSocketDataProvider * data)87*6777b538SAndroid Build Coastguard Worker void FuzzedSocketFactoryWithMockSSLData::AddSSLSocketDataProvider(
88*6777b538SAndroid Build Coastguard Worker SSLSocketDataProvider* data) {
89*6777b538SAndroid Build Coastguard Worker mock_ssl_data_.Add(data);
90*6777b538SAndroid Build Coastguard Worker }
91*6777b538SAndroid Build Coastguard Worker
92*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SSLClientSocket>
CreateSSLClientSocket(SSLClientContext * context,std::unique_ptr<StreamSocket> nested_socket,const HostPortPair & host_and_port,const SSLConfig & ssl_config)93*6777b538SAndroid Build Coastguard Worker FuzzedSocketFactoryWithMockSSLData::CreateSSLClientSocket(
94*6777b538SAndroid Build Coastguard Worker SSLClientContext* context,
95*6777b538SAndroid Build Coastguard Worker std::unique_ptr<StreamSocket> nested_socket,
96*6777b538SAndroid Build Coastguard Worker const HostPortPair& host_and_port,
97*6777b538SAndroid Build Coastguard Worker const SSLConfig& ssl_config) {
98*6777b538SAndroid Build Coastguard Worker return std::make_unique<MockSSLClientSocket>(std::move(nested_socket),
99*6777b538SAndroid Build Coastguard Worker host_and_port, ssl_config,
100*6777b538SAndroid Build Coastguard Worker mock_ssl_data_.GetNext());
101*6777b538SAndroid Build Coastguard Worker }
102*6777b538SAndroid Build Coastguard Worker
103*6777b538SAndroid Build Coastguard Worker } // namespace
104*6777b538SAndroid Build Coastguard Worker
105*6777b538SAndroid Build Coastguard Worker } // namespace net
106*6777b538SAndroid Build Coastguard Worker
107*6777b538SAndroid Build Coastguard Worker // Fuzzer for SpdySession
108*6777b538SAndroid Build Coastguard Worker //
109*6777b538SAndroid Build Coastguard Worker // |data| is used to create a FuzzedServerSocket.
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)110*6777b538SAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
111*6777b538SAndroid Build Coastguard Worker // Including an observer; even though the recorded results aren't currently
112*6777b538SAndroid Build Coastguard Worker // used, it'll ensure the netlogging code is fuzzed as well.
113*6777b538SAndroid Build Coastguard Worker net::RecordingNetLogObserver net_log_observer;
114*6777b538SAndroid Build Coastguard Worker net::NetLogWithSource net_log_with_source =
115*6777b538SAndroid Build Coastguard Worker net::NetLogWithSource::Make(net::NetLogSourceType::NONE);
116*6777b538SAndroid Build Coastguard Worker FuzzedDataProvider data_provider(data, size);
117*6777b538SAndroid Build Coastguard Worker net::FuzzedSocketFactoryWithMockSSLData socket_factory(&data_provider);
118*6777b538SAndroid Build Coastguard Worker socket_factory.set_fuzz_connect_result(false);
119*6777b538SAndroid Build Coastguard Worker
120*6777b538SAndroid Build Coastguard Worker net::SSLSocketDataProvider ssl_provider(net::ASYNC, net::OK);
121*6777b538SAndroid Build Coastguard Worker ssl_provider.ssl_info.cert = net::X509Certificate::CreateFromBytes(kCertData);
122*6777b538SAndroid Build Coastguard Worker CHECK(ssl_provider.ssl_info.cert);
123*6777b538SAndroid Build Coastguard Worker socket_factory.AddSSLSocketDataProvider(&ssl_provider);
124*6777b538SAndroid Build Coastguard Worker
125*6777b538SAndroid Build Coastguard Worker net::SpdySessionDependencies deps;
126*6777b538SAndroid Build Coastguard Worker std::unique_ptr<net::HttpNetworkSession> http_session(
127*6777b538SAndroid Build Coastguard Worker net::SpdySessionDependencies::SpdyCreateSessionWithSocketFactory(
128*6777b538SAndroid Build Coastguard Worker &deps, &socket_factory));
129*6777b538SAndroid Build Coastguard Worker
130*6777b538SAndroid Build Coastguard Worker net::SpdySessionKey session_key(
131*6777b538SAndroid Build Coastguard Worker net::HostPortPair("127.0.0.1", 80), net::PRIVACY_MODE_DISABLED,
132*6777b538SAndroid Build Coastguard Worker net::ProxyChain::Direct(), net::SessionUsage::kDestination,
133*6777b538SAndroid Build Coastguard Worker net::SocketTag(), net::NetworkAnonymizationKey(),
134*6777b538SAndroid Build Coastguard Worker net::SecureDnsPolicy::kAllow,
135*6777b538SAndroid Build Coastguard Worker /*disable_cert_verification_network_fetches=*/false);
136*6777b538SAndroid Build Coastguard Worker base::WeakPtr<net::SpdySession> spdy_session(net::CreateSpdySession(
137*6777b538SAndroid Build Coastguard Worker http_session.get(), session_key, net_log_with_source));
138*6777b538SAndroid Build Coastguard Worker
139*6777b538SAndroid Build Coastguard Worker net::SpdyStreamRequest stream_request;
140*6777b538SAndroid Build Coastguard Worker base::WeakPtr<net::SpdyStream> stream;
141*6777b538SAndroid Build Coastguard Worker
142*6777b538SAndroid Build Coastguard Worker net::TestCompletionCallback wait_for_start;
143*6777b538SAndroid Build Coastguard Worker int rv = stream_request.StartRequest(
144*6777b538SAndroid Build Coastguard Worker net::SPDY_REQUEST_RESPONSE_STREAM, spdy_session,
145*6777b538SAndroid Build Coastguard Worker GURL("http://www.example.invalid/"), /*can_send_early=*/false,
146*6777b538SAndroid Build Coastguard Worker net::DEFAULT_PRIORITY, net::SocketTag(), net_log_with_source,
147*6777b538SAndroid Build Coastguard Worker wait_for_start.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker if (rv == net::ERR_IO_PENDING) {
150*6777b538SAndroid Build Coastguard Worker rv = wait_for_start.WaitForResult();
151*6777b538SAndroid Build Coastguard Worker }
152*6777b538SAndroid Build Coastguard Worker
153*6777b538SAndroid Build Coastguard Worker // Re-check the status after potential event loop.
154*6777b538SAndroid Build Coastguard Worker if (rv != net::OK) {
155*6777b538SAndroid Build Coastguard Worker LOG(WARNING) << "StartRequest failed with result=" << rv;
156*6777b538SAndroid Build Coastguard Worker return 0;
157*6777b538SAndroid Build Coastguard Worker }
158*6777b538SAndroid Build Coastguard Worker
159*6777b538SAndroid Build Coastguard Worker stream = stream_request.ReleaseStream();
160*6777b538SAndroid Build Coastguard Worker stream->SendRequestHeaders(
161*6777b538SAndroid Build Coastguard Worker net::SpdyTestUtil::ConstructGetHeaderBlock("http://www.example.invalid"),
162*6777b538SAndroid Build Coastguard Worker net::NO_MORE_DATA_TO_SEND);
163*6777b538SAndroid Build Coastguard Worker
164*6777b538SAndroid Build Coastguard Worker base::RunLoop run_loop;
165*6777b538SAndroid Build Coastguard Worker FuzzerDelegate delegate(run_loop.QuitClosure());
166*6777b538SAndroid Build Coastguard Worker stream->SetDelegate(&delegate);
167*6777b538SAndroid Build Coastguard Worker run_loop.Run();
168*6777b538SAndroid Build Coastguard Worker
169*6777b538SAndroid Build Coastguard Worker // Give a chance for GOING_AWAY sessions to wrap up.
170*6777b538SAndroid Build Coastguard Worker base::RunLoop().RunUntilIdle();
171*6777b538SAndroid Build Coastguard Worker
172*6777b538SAndroid Build Coastguard Worker return 0;
173*6777b538SAndroid Build Coastguard Worker }
174