From 8fa0776f1f79e91fc9c0b9c1ba11a0a29c05196b Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 4 Feb 2022 17:20:24 +0100 Subject: BASELINE: Update Chromium to 98.0.4758.90 Change-Id: Ib7c41539bf8a8e0376bd639f27d68294de90f3c8 Reviewed-by: Allan Sandfeld Jensen --- chromium/net/server/BUILD.gn | 28 ++- chromium/net/server/http_connection.h | 1 - chromium/net/server/http_server.cc | 2 +- chromium/net/server/http_server.h | 4 +- chromium/net/server/http_server_fuzzer.cc | 9 +- chromium/net/server/http_server_unittest.cc | 297 ++++++++++++++++++++++++++-- chromium/net/server/web_socket.h | 6 +- chromium/net/server/web_socket_encoder.cc | 38 ++-- chromium/net/server/web_socket_encoder.h | 1 - 9 files changed, 335 insertions(+), 51 deletions(-) (limited to 'chromium/net/server') diff --git a/chromium/net/server/BUILD.gn b/chromium/net/server/BUILD.gn index 0a439b5ea1f..fb3d3ffb55e 100644 --- a/chromium/net/server/BUILD.gn +++ b/chromium/net/server/BUILD.gn @@ -11,12 +11,12 @@ static_library("http_server") { # This target is being deprecated. Use //services/network/public/cpp/server # instead. visibility = [ - ":net_http_server_fuzzer", + ":net_http_server_fuzzer_deps", ":tests", "//chrome/browser/devtools", "//chrome/test/chromedriver/*", "//content/browser", - "//net:net_web_socket_encoder_fuzzer", + "//net:net_web_socket_encoder_fuzzer_deps", ] friend = [ @@ -70,16 +70,32 @@ source_set("tests") { } } -if (enable_websockets) { - fuzzer_test("net_http_server_fuzzer") { - sources = [ "http_server_fuzzer.cc" ] - deps = [ +if (enable_websockets && use_fuzzing_engine) { + # This is a separate target because //net/server:http_server + # wants to limit its visibility to a select number of target, but the + # "fuzzer_test" template expands on iOS to many targets that need to + # have the "deps" information propagated in order to support "fat" + # binaries. + source_set("net_http_server_fuzzer_deps") { + testonly = true + visibility = [ + ":net_http_server_fuzzer", + ":net_http_server_fuzzer_arch_executable", + ":net_http_server_fuzzer_arch_executable_sources", + ":run_net_http_server_fuzzer", + ] + public_deps = [ ":http_server", "//base", "//net", "//net:net_fuzzer_test_support", "//net:test_support", ] + } + + fuzzer_test("net_http_server_fuzzer") { + sources = [ "http_server_fuzzer.cc" ] + deps = [ ":net_http_server_fuzzer_deps" ] dict = "//net/data/fuzzer_dictionaries/net_http_server_fuzzer.dict" seed_corpus = "//net/data/fuzzer_data/http_server_requests/" } diff --git a/chromium/net/server/http_connection.h b/chromium/net/server/http_connection.h index e16b3826fd8..8f3eaa0d71a 100644 --- a/chromium/net/server/http_connection.h +++ b/chromium/net/server/http_connection.h @@ -9,7 +9,6 @@ #include #include "base/containers/queue.h" -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "net/base/io_buffer.h" diff --git a/chromium/net/server/http_server.cc b/chromium/net/server/http_server.cc index fdfc5690d49..909ed5c653d 100644 --- a/chromium/net/server/http_server.cc +++ b/chromium/net/server/http_server.cc @@ -10,10 +10,10 @@ #include "base/compiler_specific.h" #include "base/location.h" #include "base/logging.h" -#include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/sys_byteorder.h" +#include "base/task/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "net/base/net_errors.h" diff --git a/chromium/net/server/http_server.h b/chromium/net/server/http_server.h index f866422350f..7ca94069a5c 100644 --- a/chromium/net/server/http_server.h +++ b/chromium/net/server/http_server.h @@ -12,7 +12,7 @@ #include #include -#include "base/macros.h" +#include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "base/strings/string_piece.h" #include "net/http/http_status_code.h" @@ -130,7 +130,7 @@ class HttpServer { const std::unique_ptr server_socket_; std::unique_ptr accepted_socket_; - HttpServer::Delegate* const delegate_; + const raw_ptr delegate_; int last_id_; std::map> id_to_connection_; diff --git a/chromium/net/server/http_server_fuzzer.cc b/chromium/net/server/http_server_fuzzer.cc index 5ebebd80014..f9c9c5e4416 100644 --- a/chromium/net/server/http_server_fuzzer.cc +++ b/chromium/net/server/http_server_fuzzer.cc @@ -5,9 +5,9 @@ #include #include "base/check_op.h" -#include "base/macros.h" #include "base/run_loop.h" #include "net/base/net_errors.h" +#include "net/log/net_log.h" #include "net/log/test_net_log.h" #include "net/server/http_server.h" #include "net/socket/fuzzed_server_socket.h" @@ -101,11 +101,14 @@ class WaitTillHttpCloseDelegate : public net::HttpServer::Delegate { // // |data| is used to create a FuzzedServerSocket. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - net::RecordingTestNetLog test_net_log; + // Including an observer; even though the recorded results aren't currently + // used, it'll ensure the netlogging code is fuzzed as well. + net::RecordingNetLogObserver net_log_observer; FuzzedDataProvider data_provider(data, size); std::unique_ptr server_socket( - std::make_unique(&data_provider, &test_net_log)); + std::make_unique(&data_provider, + net::NetLog::Get())); CHECK_EQ(net::OK, server_socket->ListenWithAddressAndPort("127.0.0.1", 80, 5)); diff --git a/chromium/net/server/http_server_unittest.cc b/chromium/net/server/http_server_unittest.cc index b57c5cd21c6..4c59764ee5d 100644 --- a/chromium/net/server/http_server_unittest.cc +++ b/chromium/net/server/http_server_unittest.cc @@ -25,10 +25,10 @@ #include "base/memory/weak_ptr.h" #include "base/notreached.h" #include "base/run_loop.h" -#include "base/single_thread_task_runner.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "base/task/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "net/base/address_list.h" @@ -322,21 +322,26 @@ class WebSocketAcceptingTest : public WebSocketTest { void OnWebSocketMessage(int connection_id, std::string data) override { message_ = data; - if (message_.length() > 0 && run_loop_) { + got_message_ = true; + if (run_loop_) { run_loop_->Quit(); } } - std::string GetMessage() { - run_loop_ = std::make_unique(); - run_loop_->Run(); - run_loop_.reset(); + const std::string& GetMessage() { + if (!got_message_) { + run_loop_ = std::make_unique(); + run_loop_->Run(); + run_loop_.reset(); + } + got_message_ = false; return message_; } private: std::string message_; std::unique_ptr run_loop_; + bool got_message_ = false; }; std::string EncodeFrame(std::string message, @@ -354,7 +359,7 @@ std::string EncodeFrame(std::string message, WebSocketMaskingKey masking_key = GenerateWebSocketMaskingKey(); WriteWebSocketFrameHeader(header, &masking_key, &frame_header[0], header_size); - MaskWebSocketFramePayload(masking_key, 0, &message[0], message.length()); + MaskWebSocketFramePayload(masking_key, 0, &message[0], message.size()); } else { WriteWebSocketFrameHeader(header, nullptr, &frame_header[0], header_size); } @@ -622,24 +627,276 @@ TEST_F(WebSocketAcceptingTest, SendLongTextFrame) { "Sec-WebSocket-Key: key\r\n\r\n"); RunUntilRequestsReceived(1); ASSERT_TRUE(client.ReadResponse(&response)); - constexpr int kMessageSize = 100000; - const std::string text_message(kMessageSize, 'a'); - const std::string continuation_message(kMessageSize, 'b'); - const std::string text_frame = - EncodeFrame(text_message, WebSocketFrameHeader::OpCodeEnum::kOpCodeText, + constexpr int kFrameSize = 100000; + const std::string text_frame(kFrameSize, 'a'); + const std::string continuation_frame(kFrameSize, 'b'); + const std::string text_encoded_frame = + EncodeFrame(text_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeText, /* mask= */ true, /* finish= */ false); - const std::string continuation_frame = - EncodeFrame(continuation_message, + const std::string continuation_encoded_frame = EncodeFrame( + continuation_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation, + /* mask= */ true, /* finish= */ true); + client.Send(text_encoded_frame); + client.Send(continuation_encoded_frame); + std::string received_message = GetMessage(); + EXPECT_EQ(received_message.size(), + text_frame.size() + continuation_frame.size()); + EXPECT_EQ(received_message, text_frame + continuation_frame); +} + +TEST_F(WebSocketAcceptingTest, SendTwoTextFrame) { + TestHttpClient client; + CreateConnection(&client); + std::string response; + client.Send( + "GET /test HTTP/1.1\r\n" + "Upgrade: WebSocket\r\n" + "Connection: SomethingElse, Upgrade\r\n" + "Sec-WebSocket-Version: 8\r\n" + "Sec-WebSocket-Key: key\r\n\r\n"); + RunUntilRequestsReceived(1); + ASSERT_TRUE(client.ReadResponse(&response)); + const std::string text_frame_first = "foo"; + const std::string continuation_frame_first = "bar"; + const std::string text_encoded_frame_first = EncodeFrame( + text_frame_first, WebSocketFrameHeader::OpCodeEnum::kOpCodeText, + /* mask= */ true, + /* finish= */ false); + const std::string continuation_encoded_frame_first = + EncodeFrame(continuation_frame_first, + WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation, + /* mask= */ true, /* finish= */ true); + + const std::string text_frame_second = "FOO"; + const std::string continuation_frame_second = "BAR"; + const std::string text_encoded_frame_second = EncodeFrame( + text_frame_second, WebSocketFrameHeader::OpCodeEnum::kOpCodeText, + /* mask= */ true, + /* finish= */ false); + const std::string continuation_encoded_frame_second = + EncodeFrame(continuation_frame_second, WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation, /* mask= */ true, /* finish= */ true); - client.Send(text_frame); - client.Send(continuation_frame); + + // text_encoded_frame_first -> text_encoded_frame_second + client.Send(text_encoded_frame_first); + client.Send(continuation_encoded_frame_first); std::string received_message = GetMessage(); - EXPECT_EQ( - static_cast(received_message.length()), - static_cast(text_message.length() + continuation_message.length())); - EXPECT_EQ(received_message, text_message + continuation_message); + EXPECT_EQ(received_message, "foobar"); + client.Send(text_encoded_frame_second); + client.Send(continuation_encoded_frame_second); + received_message = GetMessage(); + EXPECT_EQ(received_message, "FOOBAR"); +} + +TEST_F(WebSocketAcceptingTest, SendPingPongFrame) { + TestHttpClient client; + CreateConnection(&client); + std::string response; + client.Send( + "GET /test HTTP/1.1\r\n" + "Upgrade: WebSocket\r\n" + "Connection: SomethingElse, Upgrade\r\n" + "Sec-WebSocket-Version: 8\r\n" + "Sec-WebSocket-Key: key\r\n\r\n"); + RunUntilRequestsReceived(1); + ASSERT_TRUE(client.ReadResponse(&response)); + + const std::string ping_message_first = ""; + const std::string ping_frame_first = EncodeFrame( + ping_message_first, WebSocketFrameHeader::OpCodeEnum::kOpCodePing, + /* mask= */ true, /* finish= */ true); + const std::string pong_frame_receive_first = EncodeFrame( + ping_message_first, WebSocketFrameHeader::OpCodeEnum::kOpCodePong, + /* mask= */ false, /* finish= */ true); + const std::string pong_frame_send = EncodeFrame( + /* message= */ "", WebSocketFrameHeader::OpCodeEnum::kOpCodePong, + /* mask= */ true, /* finish= */ true); + const std::string ping_message_second = "hello"; + const std::string ping_frame_second = EncodeFrame( + ping_message_second, WebSocketFrameHeader::OpCodeEnum::kOpCodePing, + /* mask= */ true, /* finish= */ true); + const std::string pong_frame_receive_second = EncodeFrame( + ping_message_second, WebSocketFrameHeader::OpCodeEnum::kOpCodePong, + /* mask= */ false, /* finish= */ true); + + // ping_frame_first -> pong_frame_send -> ping_frame_second + client.Send(ping_frame_first); + ASSERT_TRUE(client.Read(&response, pong_frame_receive_first.length())); + EXPECT_EQ(response, pong_frame_receive_first); + client.Send(pong_frame_send); + client.Send(ping_frame_second); + ASSERT_TRUE(client.Read(&response, pong_frame_receive_second.length())); + EXPECT_EQ(response, pong_frame_receive_second); +} + +TEST_F(WebSocketAcceptingTest, SendTextAndPingFrame) { + TestHttpClient client; + CreateConnection(&client); + std::string response; + client.Send( + "GET /test HTTP/1.1\r\n" + "Upgrade: WebSocket\r\n" + "Connection: SomethingElse, Upgrade\r\n" + "Sec-WebSocket-Version: 8\r\n" + "Sec-WebSocket-Key: key\r\n\r\n"); + RunUntilRequestsReceived(1); + ASSERT_TRUE(client.ReadResponse(&response)); + + const std::string text_frame = "foo"; + const std::string continuation_frame = "bar"; + const std::string text_encoded_frame = + EncodeFrame(text_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeText, + /* mask= */ true, + /* finish= */ false); + const std::string continuation_encoded_frame = EncodeFrame( + continuation_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation, + /* mask= */ true, /* finish= */ true); + const std::string ping_message = "ping"; + const std::string ping_frame = + EncodeFrame(ping_message, WebSocketFrameHeader::OpCodeEnum::kOpCodePing, + /* mask= */ true, /* finish= */ true); + const std::string pong_frame = + EncodeFrame(ping_message, WebSocketFrameHeader::OpCodeEnum::kOpCodePong, + /* mask= */ false, /* finish= */ true); + + // text_encoded_frame -> ping_frame -> continuation_encoded_frame + client.Send(text_encoded_frame); + client.Send(ping_frame); + client.Send(continuation_encoded_frame); + ASSERT_TRUE(client.Read(&response, pong_frame.length())); + EXPECT_EQ(response, pong_frame); + std::string received_message = GetMessage(); + EXPECT_EQ(received_message, "foobar"); +} + +TEST_F(WebSocketAcceptingTest, SendTextAndPingFrameWithMessage) { + TestHttpClient client; + CreateConnection(&client); + std::string response; + client.Send( + "GET /test HTTP/1.1\r\n" + "Upgrade: WebSocket\r\n" + "Connection: SomethingElse, Upgrade\r\n" + "Sec-WebSocket-Version: 8\r\n" + "Sec-WebSocket-Key: key\r\n\r\n"); + RunUntilRequestsReceived(1); + ASSERT_TRUE(client.ReadResponse(&response)); + + const std::string text_frame = "foo"; + const std::string continuation_frame = "bar"; + const std::string text_encoded_frame = + EncodeFrame(text_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeText, + /* mask= */ true, + /* finish= */ false); + const std::string continuation_encoded_frame = EncodeFrame( + continuation_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation, + /* mask= */ true, /* finish= */ true); + const std::string ping_message = "hello"; + const std::string ping_frame = + EncodeFrame(ping_message, WebSocketFrameHeader::OpCodeEnum::kOpCodePing, + /* mask= */ true, /* finish= */ true); + const std::string pong_frame = + EncodeFrame(ping_message, WebSocketFrameHeader::OpCodeEnum::kOpCodePong, + /* mask= */ false, /* finish= */ true); + + // text_encoded_frame -> ping_frame -> continuation_frame + client.Send(text_encoded_frame); + client.Send(ping_frame); + client.Send(continuation_encoded_frame); + ASSERT_TRUE(client.Read(&response, pong_frame.length())); + EXPECT_EQ(response, pong_frame); + std::string received_message = GetMessage(); + EXPECT_EQ(received_message, "foobar"); +} + +TEST_F(WebSocketAcceptingTest, SendTextAndPongFrame) { + TestHttpClient client; + CreateConnection(&client); + std::string response; + client.Send( + "GET /test HTTP/1.1\r\n" + "Upgrade: WebSocket\r\n" + "Connection: SomethingElse, Upgrade\r\n" + "Sec-WebSocket-Version: 8\r\n" + "Sec-WebSocket-Key: key\r\n\r\n"); + RunUntilRequestsReceived(1); + ASSERT_TRUE(client.ReadResponse(&response)); + + const std::string text_frame = "foo"; + const std::string continuation_frame = "bar"; + const std::string text_encoded_frame = + EncodeFrame(text_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeText, + /* mask= */ true, + /* finish= */ false); + const std::string continuation_encoded_frame = EncodeFrame( + continuation_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation, + /* mask= */ true, /* finish= */ true); + const std::string pong_message = "pong"; + const std::string pong_frame = + EncodeFrame(pong_message, WebSocketFrameHeader::OpCodeEnum::kOpCodePong, + /* mask= */ true, /* finish= */ true); + + // text_encoded_frame -> pong_frame -> continuation_encoded_frame + client.Send(text_encoded_frame); + client.Send(pong_frame); + client.Send(continuation_encoded_frame); + std::string received_message = GetMessage(); + EXPECT_EQ(received_message, "foobar"); +} + +TEST_F(WebSocketAcceptingTest, SendTextPingPongFrame) { + TestHttpClient client; + CreateConnection(&client); + std::string response; + client.Send( + "GET /test HTTP/1.1\r\n" + "Upgrade: WebSocket\r\n" + "Connection: SomethingElse, Upgrade\r\n" + "Sec-WebSocket-Version: 8\r\n" + "Sec-WebSocket-Key: key\r\n\r\n"); + RunUntilRequestsReceived(1); + ASSERT_TRUE(client.ReadResponse(&response)); + + const std::string text_frame = "foo"; + const std::string continuation_frame = "bar"; + const std::string text_encoded_frame = + EncodeFrame(text_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeText, + /* mask= */ true, + /* finish= */ false); + const std::string continuation_encoded_frame = EncodeFrame( + continuation_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation, + /* mask= */ true, /* finish= */ true); + + const std::string ping_message_first = "hello"; + const std::string ping_frame_first = EncodeFrame( + ping_message_first, WebSocketFrameHeader::OpCodeEnum::kOpCodePing, + /* mask= */ true, /* finish= */ true); + const std::string pong_frame_first = EncodeFrame( + ping_message_first, WebSocketFrameHeader::OpCodeEnum::kOpCodePong, + /* mask= */ false, /* finish= */ true); + + const std::string ping_message_second = "HELLO"; + const std::string ping_frame_second = EncodeFrame( + ping_message_second, WebSocketFrameHeader::OpCodeEnum::kOpCodePing, + /* mask= */ true, /* finish= */ true); + const std::string pong_frame_second = EncodeFrame( + ping_message_second, WebSocketFrameHeader::OpCodeEnum::kOpCodePong, + /* mask= */ false, /* finish= */ true); + + // text_encoded_frame -> ping_frame_first -> ping_frame_second -> + // continuation_encoded_frame + client.Send(text_encoded_frame); + client.Send(ping_frame_first); + ASSERT_TRUE(client.Read(&response, pong_frame_first.length())); + EXPECT_EQ(response, pong_frame_first); + client.Send(ping_frame_second); + ASSERT_TRUE(client.Read(&response, pong_frame_second.length())); + EXPECT_EQ(response, pong_frame_second); + client.Send(continuation_encoded_frame); + std::string received_message = GetMessage(); + EXPECT_EQ(received_message, "foobar"); } TEST_F(HttpServerTest, RequestWithTooLargeBody) { diff --git a/chromium/net/server/web_socket.h b/chromium/net/server/web_socket.h index d5c91e06413..af27eb66a3b 100644 --- a/chromium/net/server/web_socket.h +++ b/chromium/net/server/web_socket.h @@ -8,7 +8,7 @@ #include #include -#include "base/macros.h" +#include "base/memory/raw_ptr.h" #include "base/strings/string_piece.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/websockets/websocket_frame.h" @@ -53,8 +53,8 @@ class WebSocket final { void SendErrorResponse(const std::string& message, const NetworkTrafficAnnotationTag traffic_annotation); - HttpServer* const server_; - HttpConnection* const connection_; + const raw_ptr server_; + const raw_ptr connection_; std::unique_ptr encoder_; bool closed_; std::unique_ptr traffic_annotation_ = nullptr; diff --git a/chromium/net/server/web_socket_encoder.cc b/chromium/net/server/web_socket_encoder.cc index 7e5e652786b..a70e587861a 100644 --- a/chromium/net/server/web_socket_encoder.cc +++ b/chromium/net/server/web_socket_encoder.cc @@ -301,22 +301,32 @@ WebSocket::ParseResult WebSocketEncoder::DecodeFrame( std::string current_output; WebSocket::ParseResult result = DecodeFrameHybi17( frame, type_ == FOR_SERVER, bytes_consumed, ¤t_output, &compressed); - if (result == WebSocket::FRAME_OK_FINAL || - result == WebSocket::FRAME_OK_MIDDLE || result == WebSocket::FRAME_PING) { - if (continuation_message_frames_.empty()) - is_current_message_compressed_ = compressed; - continuation_message_frames_.push_back(current_output); - } - if (result == WebSocket::FRAME_OK_FINAL || result == WebSocket::FRAME_PING) { - *output = base::StrCat(continuation_message_frames_); - if (is_current_message_compressed_) { - if (!Inflate(output)) - result = WebSocket::FRAME_ERROR; + switch (result) { + case WebSocket::FRAME_OK_FINAL: + case WebSocket::FRAME_OK_MIDDLE: { + if (continuation_message_frames_.empty()) + is_current_message_compressed_ = compressed; + continuation_message_frames_.push_back(current_output); + + if (result == WebSocket::FRAME_OK_FINAL) { + *output = base::StrCat(continuation_message_frames_); + continuation_message_frames_.clear(); + if (is_current_message_compressed_ && !Inflate(output)) { + return WebSocket::FRAME_ERROR; + } + } + break; } + + case WebSocket::FRAME_PING: + *output = current_output; + break; + + default: + // This function doesn't need special handling for other parse results. + break; } - if (result != WebSocket::FRAME_OK_MIDDLE && - result != WebSocket::FRAME_INCOMPLETE) - continuation_message_frames_.clear(); + return result; } diff --git a/chromium/net/server/web_socket_encoder.h b/chromium/net/server/web_socket_encoder.h index 3f18f00053b..66b3d7a51eb 100644 --- a/chromium/net/server/web_socket_encoder.h +++ b/chromium/net/server/web_socket_encoder.h @@ -9,7 +9,6 @@ #include #include -#include "base/macros.h" #include "base/strings/string_piece.h" #include "net/server/web_socket.h" #include "net/websockets/websocket_deflater.h" -- cgit v1.2.1