xref: /aosp_15_r20/external/cronet/net/server/http_server_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 "base/check_op.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
10*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
11*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log.h"
12*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/server/http_server.h"
14*6777b538SAndroid Build Coastguard Worker #include "net/socket/fuzzed_server_socket.h"
15*6777b538SAndroid Build Coastguard Worker #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker namespace {
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker class WaitTillHttpCloseDelegate : public net::HttpServer::Delegate {
20*6777b538SAndroid Build Coastguard Worker  public:
WaitTillHttpCloseDelegate(FuzzedDataProvider * data_provider,base::OnceClosure done_closure)21*6777b538SAndroid Build Coastguard Worker   WaitTillHttpCloseDelegate(FuzzedDataProvider* data_provider,
22*6777b538SAndroid Build Coastguard Worker                             base::OnceClosure done_closure)
23*6777b538SAndroid Build Coastguard Worker       : data_provider_(data_provider),
24*6777b538SAndroid Build Coastguard Worker         done_closure_(std::move(done_closure)),
25*6777b538SAndroid Build Coastguard Worker         action_flags_(data_provider_->ConsumeIntegral<uint8_t>()) {}
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker   WaitTillHttpCloseDelegate(const WaitTillHttpCloseDelegate&) = delete;
28*6777b538SAndroid Build Coastguard Worker   WaitTillHttpCloseDelegate& operator=(const WaitTillHttpCloseDelegate&) =
29*6777b538SAndroid Build Coastguard Worker       delete;
30*6777b538SAndroid Build Coastguard Worker 
set_server(net::HttpServer * server)31*6777b538SAndroid Build Coastguard Worker   void set_server(net::HttpServer* server) { server_ = server; }
32*6777b538SAndroid Build Coastguard Worker 
OnConnect(int connection_id)33*6777b538SAndroid Build Coastguard Worker   void OnConnect(int connection_id) override {
34*6777b538SAndroid Build Coastguard Worker     if (!(action_flags_ & ACCEPT_CONNECTION))
35*6777b538SAndroid Build Coastguard Worker       server_->Close(connection_id);
36*6777b538SAndroid Build Coastguard Worker   }
37*6777b538SAndroid Build Coastguard Worker 
OnHttpRequest(int connection_id,const net::HttpServerRequestInfo & info)38*6777b538SAndroid Build Coastguard Worker   void OnHttpRequest(int connection_id,
39*6777b538SAndroid Build Coastguard Worker                      const net::HttpServerRequestInfo& info) override {
40*6777b538SAndroid Build Coastguard Worker     if (!(action_flags_ & ACCEPT_MESSAGE)) {
41*6777b538SAndroid Build Coastguard Worker       server_->Close(connection_id);
42*6777b538SAndroid Build Coastguard Worker       return;
43*6777b538SAndroid Build Coastguard Worker     }
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker     if (action_flags_ & REPLY_TO_MESSAGE) {
46*6777b538SAndroid Build Coastguard Worker       server_->Send200(connection_id,
47*6777b538SAndroid Build Coastguard Worker                        data_provider_->ConsumeRandomLengthString(64),
48*6777b538SAndroid Build Coastguard Worker                        "text/html", TRAFFIC_ANNOTATION_FOR_TESTS);
49*6777b538SAndroid Build Coastguard Worker     }
50*6777b538SAndroid Build Coastguard Worker   }
51*6777b538SAndroid Build Coastguard Worker 
OnWebSocketRequest(int connection_id,const net::HttpServerRequestInfo & info)52*6777b538SAndroid Build Coastguard Worker   void OnWebSocketRequest(int connection_id,
53*6777b538SAndroid Build Coastguard Worker                           const net::HttpServerRequestInfo& info) override {
54*6777b538SAndroid Build Coastguard Worker     if (action_flags_ & CLOSE_WEBSOCKET_RATHER_THAN_ACCEPT) {
55*6777b538SAndroid Build Coastguard Worker       server_->Close(connection_id);
56*6777b538SAndroid Build Coastguard Worker       return;
57*6777b538SAndroid Build Coastguard Worker     }
58*6777b538SAndroid Build Coastguard Worker 
59*6777b538SAndroid Build Coastguard Worker     if (action_flags_ & ACCEPT_WEBSOCKET)
60*6777b538SAndroid Build Coastguard Worker       server_->AcceptWebSocket(connection_id, info,
61*6777b538SAndroid Build Coastguard Worker                                TRAFFIC_ANNOTATION_FOR_TESTS);
62*6777b538SAndroid Build Coastguard Worker   }
63*6777b538SAndroid Build Coastguard Worker 
OnWebSocketMessage(int connection_id,std::string data)64*6777b538SAndroid Build Coastguard Worker   void OnWebSocketMessage(int connection_id, std::string data) override {
65*6777b538SAndroid Build Coastguard Worker     if (!(action_flags_ & ACCEPT_MESSAGE)) {
66*6777b538SAndroid Build Coastguard Worker       server_->Close(connection_id);
67*6777b538SAndroid Build Coastguard Worker       return;
68*6777b538SAndroid Build Coastguard Worker     }
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker     if (action_flags_ & REPLY_TO_MESSAGE) {
71*6777b538SAndroid Build Coastguard Worker       server_->SendOverWebSocket(connection_id,
72*6777b538SAndroid Build Coastguard Worker                                  data_provider_->ConsumeRandomLengthString(64),
73*6777b538SAndroid Build Coastguard Worker                                  TRAFFIC_ANNOTATION_FOR_TESTS);
74*6777b538SAndroid Build Coastguard Worker     }
75*6777b538SAndroid Build Coastguard Worker   }
76*6777b538SAndroid Build Coastguard Worker 
OnClose(int connection_id)77*6777b538SAndroid Build Coastguard Worker   void OnClose(int connection_id) override {
78*6777b538SAndroid Build Coastguard Worker     // In general, OnClose can be called more than once, but FuzzedServerSocket
79*6777b538SAndroid Build Coastguard Worker     // only makes one connection, and it is the only socket of interest here.
80*6777b538SAndroid Build Coastguard Worker     std::move(done_closure_).Run();
81*6777b538SAndroid Build Coastguard Worker   }
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker  private:
84*6777b538SAndroid Build Coastguard Worker   enum {
85*6777b538SAndroid Build Coastguard Worker     ACCEPT_CONNECTION = 1,
86*6777b538SAndroid Build Coastguard Worker     ACCEPT_MESSAGE = 2,
87*6777b538SAndroid Build Coastguard Worker     REPLY_TO_MESSAGE = 4,
88*6777b538SAndroid Build Coastguard Worker     ACCEPT_WEBSOCKET = 8,
89*6777b538SAndroid Build Coastguard Worker     CLOSE_WEBSOCKET_RATHER_THAN_ACCEPT = 16
90*6777b538SAndroid Build Coastguard Worker   };
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   raw_ptr<net::HttpServer> server_ = nullptr;
93*6777b538SAndroid Build Coastguard Worker   const raw_ptr<FuzzedDataProvider> data_provider_;
94*6777b538SAndroid Build Coastguard Worker   base::OnceClosure done_closure_;
95*6777b538SAndroid Build Coastguard Worker   const uint8_t action_flags_;
96*6777b538SAndroid Build Coastguard Worker };
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker }  // namespace
99*6777b538SAndroid Build Coastguard Worker 
100*6777b538SAndroid Build Coastguard Worker // Fuzzer for HttpServer
101*6777b538SAndroid Build Coastguard Worker //
102*6777b538SAndroid Build Coastguard Worker // |data| is used to create a FuzzedServerSocket.
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)103*6777b538SAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
104*6777b538SAndroid Build Coastguard Worker   // Including an observer; even though the recorded results aren't currently
105*6777b538SAndroid Build Coastguard Worker   // used, it'll ensure the netlogging code is fuzzed as well.
106*6777b538SAndroid Build Coastguard Worker   net::RecordingNetLogObserver net_log_observer;
107*6777b538SAndroid Build Coastguard Worker   FuzzedDataProvider data_provider(data, size);
108*6777b538SAndroid Build Coastguard Worker 
109*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<net::ServerSocket> server_socket(
110*6777b538SAndroid Build Coastguard Worker       std::make_unique<net::FuzzedServerSocket>(&data_provider,
111*6777b538SAndroid Build Coastguard Worker                                                 net::NetLog::Get()));
112*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(net::OK,
113*6777b538SAndroid Build Coastguard Worker            server_socket->ListenWithAddressAndPort("127.0.0.1", 80, 5));
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker   base::RunLoop run_loop;
116*6777b538SAndroid Build Coastguard Worker   WaitTillHttpCloseDelegate delegate(&data_provider, run_loop.QuitClosure());
117*6777b538SAndroid Build Coastguard Worker   net::HttpServer server(std::move(server_socket), &delegate);
118*6777b538SAndroid Build Coastguard Worker   delegate.set_server(&server);
119*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
120*6777b538SAndroid Build Coastguard Worker   return 0;
121*6777b538SAndroid Build Coastguard Worker }
122