diff options
author | ricea@chromium.org <ricea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-26 13:11:35 +0000 |
---|---|---|
committer | ricea@chromium.org <ricea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-26 13:11:35 +0000 |
commit | 658d767ebecc3fdf6f68b0832d370c4749da15cb (patch) | |
tree | 29001fe37532ca9bd6f2d13f255d0bacf8b46f29 /net/websockets | |
parent | 1cdea06deb4c1253516c450b1a89af7544931f94 (diff) | |
download | chromium_src-658d767ebecc3fdf6f68b0832d370c4749da15cb.zip chromium_src-658d767ebecc3fdf6f68b0832d370c4749da15cb.tar.gz chromium_src-658d767ebecc3fdf6f68b0832d370c4749da15cb.tar.bz2 |
net::WebSocketChannel should reject reserved bits
Check the RSV1, RSV2 and RSV3 bits in WebSocketChannel::HandleFrame and
fail the connection if they are set.
Document the requirement for extensions to clear the bits when validly
set in WebSocketStream.
BUG=346211
TEST=net_unittests, compressed-control-frame.html layout test
Review URL: https://codereview.chromium.org/177403002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253423 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/websockets')
-rw-r--r-- | net/websockets/websocket_channel.cc | 6 | ||||
-rw-r--r-- | net/websockets/websocket_channel_test.cc | 24 | ||||
-rw-r--r-- | net/websockets/websocket_stream.h | 4 |
3 files changed, 34 insertions, 0 deletions
diff --git a/net/websockets/websocket_channel.cc b/net/websockets/websocket_channel.cc index 681ad7e..96d0b76 100644 --- a/net/websockets/websocket_channel.cc +++ b/net/websockets/websocket_channel.cc @@ -656,6 +656,12 @@ ChannelState WebSocketChannel::HandleFrame( kWebSocketErrorProtocolError, "Control message with FIN bit unset received"); } + if (frame->header.reserved1 || frame->header.reserved2 || + frame->header.reserved3) { + return FailChannel("Received a frame with an invalid reserved bit set.", + kWebSocketErrorProtocolError, + "Invalid reserved bit"); + } // Respond to the frame appropriately to its type. return HandleFrameByState( diff --git a/net/websockets/websocket_channel_test.cc b/net/websockets/websocket_channel_test.cc index 02d495a..f82b3ef 100644 --- a/net/websockets/websocket_channel_test.cc +++ b/net/websockets/websocket_channel_test.cc @@ -2075,6 +2075,30 @@ TEST_F(WebSocketChannelEventInterfaceTest, ClosePayloadInvalidReason) { CreateChannelAndConnectSuccessfully(); } +// The reserved bits must all be clear on received frames. Extensions should +// clear the bits when they are set correctly before passing on the frame. +TEST_F(WebSocketChannelEventInterfaceTest, ReservedBitsMustNotBeSet) { + scoped_ptr<ReadableFakeWebSocketStream> stream( + new ReadableFakeWebSocketStream); + static const InitFrame frames[] = { + {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, + NOT_MASKED, "sakana"}}; + // It is not worth adding support for reserved bits to InitFrame just for this + // one test, so set the bit manually. + ScopedVector<WebSocketFrame> raw_frames = CreateFrameVector(frames); + raw_frames[0]->header.reserved1 = true; + stream->PrepareRawReadFrames( + ReadableFakeWebSocketStream::SYNC, OK, raw_frames.Pass()); + set_stream(stream.Pass()); + EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); + EXPECT_CALL(*event_interface_, OnFlowControl(_)); + EXPECT_CALL( + *event_interface_, + OnFailChannel("Received a frame with an invalid reserved bit set.")); + + CreateChannelAndConnectSuccessfully(); +} + // The closing handshake times out and sends an OnDropChannel event if no // response to the client Close message is received. TEST_F(WebSocketChannelEventInterfaceTest, diff --git a/net/websockets/websocket_stream.h b/net/websockets/websocket_stream.h index a35eefa..bcc8416 100644 --- a/net/websockets/websocket_stream.h +++ b/net/websockets/websocket_stream.h @@ -134,6 +134,10 @@ class NET_EXPORT_PRIVATE WebSocketStream { // calling callback.Run() (and any calling methods in the same object) must // return immediately without any further method calls or access to member // variables. Implementors should write test(s) for this case. + // + // Extensions which use reserved header bits should clear them when they are + // set correctly. If the reserved header bits are set incorrectly, it is okay + // to leave it to the caller to report the error. virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, const CompletionCallback& callback) = 0; |