xref: /aosp_15_r20/external/cronet/net/spdy/spdy_session_fuzzer.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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