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