quic_stream_factory_fuzzer.cc 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 2017 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. #include "net/quic/quic_stream_factory.h"
  5. #include <fuzzer/FuzzedDataProvider.h>
  6. #include "base/cxx17_backports.h"
  7. #include "net/base/network_isolation_key.h"
  8. #include "net/base/test_completion_callback.h"
  9. #include "net/cert/ct_policy_enforcer.h"
  10. #include "net/cert/do_nothing_ct_verifier.h"
  11. #include "net/cert/mock_cert_verifier.h"
  12. #include "net/cert/x509_certificate.h"
  13. #include "net/dns/context_host_resolver.h"
  14. #include "net/dns/fuzzed_host_resolver_util.h"
  15. #include "net/dns/public/secure_dns_policy.h"
  16. #include "net/http/http_server_properties.h"
  17. #include "net/http/transport_security_state.h"
  18. #include "net/quic/mock_crypto_client_stream_factory.h"
  19. #include "net/quic/mock_quic_context.h"
  20. #include "net/quic/quic_http_stream.h"
  21. #include "net/quic/test_task_runner.h"
  22. #include "net/socket/fuzzed_datagram_client_socket.h"
  23. #include "net/socket/fuzzed_socket_factory.h"
  24. #include "net/socket/socket_tag.h"
  25. #include "net/ssl/ssl_config_service_defaults.h"
  26. #include "net/test/gtest_util.h"
  27. #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
  28. #include "url/scheme_host_port.h"
  29. #include "url/url_constants.h"
  30. namespace net {
  31. namespace {
  32. const uint8_t kCertData[] = {
  33. #include "net/data/ssl/certificates/wildcard.inc"
  34. };
  35. } // namespace
  36. namespace test {
  37. const char kServerHostName[] = "www.example.org";
  38. const int kServerPort = 443;
  39. const char kUrl[] = "https://www.example.org/";
  40. // TODO(nedwilliamson): Add POST here after testing
  41. // whether that can lead blocking while waiting for
  42. // the callbacks.
  43. const char kMethod[] = "GET";
  44. const size_t kBufferSize = 4096;
  45. const int kCertVerifyFlags = 0;
  46. // Static initialization for persistent factory data
  47. struct Env {
  48. Env() : scheme_host_port(url::kHttpsScheme, kServerHostName, kServerPort) {
  49. quic_context.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
  50. ssl_config_service = std::make_unique<SSLConfigServiceDefaults>();
  51. crypto_client_stream_factory.set_use_mock_crypter(true);
  52. cert_verifier = std::make_unique<MockCertVerifier>();
  53. verify_details.cert_verify_result.verified_cert =
  54. X509Certificate::CreateFromBytes(kCertData);
  55. CHECK(verify_details.cert_verify_result.verified_cert);
  56. verify_details.cert_verify_result.is_issued_by_known_root = true;
  57. }
  58. std::unique_ptr<SSLConfigService> ssl_config_service;
  59. ProofVerifyDetailsChromium verify_details;
  60. MockCryptoClientStreamFactory crypto_client_stream_factory;
  61. url::SchemeHostPort scheme_host_port;
  62. NetLogWithSource net_log;
  63. std::unique_ptr<CertVerifier> cert_verifier;
  64. TransportSecurityState transport_security_state;
  65. quic::QuicTagVector connection_options;
  66. quic::QuicTagVector client_connection_options;
  67. DefaultCTPolicyEnforcer ct_policy_enforcer;
  68. MockQuicContext quic_context;
  69. };
  70. static struct Env* env = new Env();
  71. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  72. FuzzedDataProvider data_provider(data, size);
  73. std::unique_ptr<ContextHostResolver> host_resolver =
  74. CreateFuzzedContextHostResolver(HostResolver::ManagerOptions(), nullptr,
  75. &data_provider,
  76. true /* enable_caching */);
  77. FuzzedSocketFactory socket_factory(&data_provider);
  78. // Initialize this on each loop since some options mutate this.
  79. HttpServerProperties http_server_properties;
  80. QuicParams& params = *env->quic_context.params();
  81. params.max_server_configs_stored_in_properties =
  82. data_provider.ConsumeBool() ? 1 : 0;
  83. params.close_sessions_on_ip_change = data_provider.ConsumeBool();
  84. params.allow_server_migration = data_provider.ConsumeBool();
  85. params.estimate_initial_rtt = data_provider.ConsumeBool();
  86. params.headers_include_h2_stream_dependency = data_provider.ConsumeBool();
  87. params.enable_socket_recv_optimization = data_provider.ConsumeBool();
  88. params.race_stale_dns_on_connection = data_provider.ConsumeBool();
  89. env->crypto_client_stream_factory.AddProofVerifyDetails(&env->verify_details);
  90. params.goaway_sessions_on_ip_change = false;
  91. params.migrate_sessions_early_v2 = false;
  92. params.migrate_sessions_on_network_change_v2 = false;
  93. params.retry_on_alternate_network_before_handshake = false;
  94. params.migrate_idle_sessions = false;
  95. if (!params.close_sessions_on_ip_change) {
  96. params.goaway_sessions_on_ip_change = data_provider.ConsumeBool();
  97. if (!params.goaway_sessions_on_ip_change) {
  98. params.migrate_sessions_on_network_change_v2 =
  99. data_provider.ConsumeBool();
  100. if (params.migrate_sessions_on_network_change_v2) {
  101. params.migrate_sessions_early_v2 = data_provider.ConsumeBool();
  102. params.retry_on_alternate_network_before_handshake =
  103. data_provider.ConsumeBool();
  104. params.migrate_idle_sessions = data_provider.ConsumeBool();
  105. }
  106. }
  107. }
  108. std::unique_ptr<QuicStreamFactory> factory =
  109. std::make_unique<QuicStreamFactory>(
  110. env->net_log.net_log(), host_resolver.get(),
  111. env->ssl_config_service.get(), &socket_factory,
  112. &http_server_properties, env->cert_verifier.get(),
  113. &env->ct_policy_enforcer, &env->transport_security_state, nullptr,
  114. nullptr, &env->crypto_client_stream_factory, &env->quic_context);
  115. QuicStreamRequest request(factory.get());
  116. TestCompletionCallback callback;
  117. NetErrorDetails net_error_details;
  118. quic::ParsedQuicVersionVector versions = quic::AllSupportedVersions();
  119. quic::ParsedQuicVersion version =
  120. versions[data_provider.ConsumeIntegralInRange<size_t>(
  121. 0, versions.size() - 1)];
  122. quic::QuicEnableVersion(version);
  123. request.Request(
  124. env->scheme_host_port, version, PRIVACY_MODE_DISABLED, DEFAULT_PRIORITY,
  125. SocketTag(), NetworkIsolationKey(), SecureDnsPolicy::kAllow,
  126. true /* use_dns_aliases */, false /* require_dns_https_alpn */,
  127. kCertVerifyFlags, GURL(kUrl), env->net_log, &net_error_details,
  128. /*failed_on_default_network_callback=*/CompletionOnceCallback(),
  129. callback.callback());
  130. callback.WaitForResult();
  131. std::unique_ptr<QuicChromiumClientSession::Handle> session =
  132. request.ReleaseSessionHandle();
  133. if (!session)
  134. return 0;
  135. auto dns_aliases = session->GetDnsAliasesForSessionKey(request.session_key());
  136. auto stream = std::make_unique<QuicHttpStream>(std::move(session),
  137. std::move(dns_aliases));
  138. HttpRequestInfo request_info;
  139. request_info.method = kMethod;
  140. request_info.url = GURL(kUrl);
  141. request_info.traffic_annotation =
  142. MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
  143. stream->RegisterRequest(&request_info);
  144. stream->InitializeStream(true, DEFAULT_PRIORITY, env->net_log,
  145. CompletionOnceCallback());
  146. HttpResponseInfo response;
  147. HttpRequestHeaders request_headers;
  148. if (OK !=
  149. stream->SendRequest(request_headers, &response, callback.callback()))
  150. return 0;
  151. // TODO(nedwilliamson): attempt connection migration here
  152. int rv = stream->ReadResponseHeaders(callback.callback());
  153. if (rv != OK && rv != ERR_IO_PENDING) {
  154. return 0;
  155. }
  156. callback.WaitForResult();
  157. scoped_refptr<net::IOBuffer> buffer =
  158. base::MakeRefCounted<net::IOBuffer>(kBufferSize);
  159. rv = stream->ReadResponseBody(buffer.get(), kBufferSize, callback.callback());
  160. if (rv == ERR_IO_PENDING)
  161. callback.WaitForResult();
  162. return 0;
  163. }
  164. } // namespace test
  165. } // namespace net