[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
ukai at chromium.org
ukai at chromium.org
Wed Dec 22 11:54:55 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 0a388745e3f4b8def3114c9a7ef5d0d4f575d9f5
Author: ukai at chromium.org <ukai at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Aug 11 08:23:56 2010 +0000
2010-08-11 Fumitoshi Ukai <ukai at chromium.org>
Reviewed by Alexey Proskuryakov.
Fix length calculation to be more robust.
https://bugs.webkit.org/show_bug.cgi?id=43777
* websocket/tests/frame-length-overflow-expected.txt: Added.
* websocket/tests/frame-length-overflow.html: Added.
* websocket/tests/frame-length-overflow_wsh.py: Added.
2010-08-11 Fumitoshi Ukai <ukai at chromium.org>
Reviewed by Alexey Proskuryakov.
Fix length calculation to be more robust.
https://bugs.webkit.org/show_bug.cgi?id=43777
Test: websocket/tests/frame-length-overflow.html
* websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::appendToBuffer): len is size_t.
- add sanity check for integer wraps.
(WebCore::WebSocketChannel::skipBuffer): len is size_t.
(WebCore::WebSocketChannel::processBuffer): length is size_t.
- add sanity check for integer wraps.
* websockets/WebSocketChannel.h: change m_bufferSize and len to size_t.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@65135 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d0232d1..eca970e 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
+2010-08-11 Fumitoshi Ukai <ukai at chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Fix length calculation to be more robust.
+ https://bugs.webkit.org/show_bug.cgi?id=43777
+
+ * websocket/tests/frame-length-overflow-expected.txt: Added.
+ * websocket/tests/frame-length-overflow.html: Added.
+ * websocket/tests/frame-length-overflow_wsh.py: Added.
+
2010-08-10 Eric Seidel <eric at webkit.org>
Reviewed by Adam Barth.
diff --git a/LayoutTests/websocket/tests/frame-length-overflow-expected.txt b/LayoutTests/websocket/tests/frame-length-overflow-expected.txt
new file mode 100644
index 0000000..1a15207
--- /dev/null
+++ b/LayoutTests/websocket/tests/frame-length-overflow-expected.txt
@@ -0,0 +1,11 @@
+Make sure WebSocket does not crash and report error when it sees length overflow
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+WebSocket is open
+WebSocket received error frame
+WebSocket is closed
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/websocket/tests/frame-length-overflow.html b/LayoutTests/websocket/tests/frame-length-overflow.html
new file mode 100644
index 0000000..627043a
--- /dev/null
+++ b/LayoutTests/websocket/tests/frame-length-overflow.html
@@ -0,0 +1,38 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("Make sure WebSocket does not crash and report error when it sees length overflow");
+if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+
+function finish() {
+ isSuccessfullyParsed();
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+
+var ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/frame-length-overflow");
+ws.onopen = function () {
+ debug("WebSocket is open");
+};
+ws.onmessage = function (evt) {
+ debug("WebSocket received:" + evt.data);
+};
+ws.onerror = function () {
+ debug("WebSocket received error frame");
+};
+ws.onclose = function () {
+ debug("WebSocket is closed");
+ finish();
+};
+
+var successfullyParsed = true;
+</script>
+
diff --git a/LayoutTests/websocket/tests/frame-length-overflow_wsh.py b/LayoutTests/websocket/tests/frame-length-overflow_wsh.py
new file mode 100644
index 0000000..0f518a8
--- /dev/null
+++ b/LayoutTests/websocket/tests/frame-length-overflow_wsh.py
@@ -0,0 +1,6 @@
+def web_socket_do_extra_handshake(request):
+ pass
+
+def web_socket_transfer_data(request):
+ msg = 16 * '\xff'
+ request.connection.write(msg)
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 0585b5e..b3cc4ae 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,20 @@
+2010-08-11 Fumitoshi Ukai <ukai at chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Fix length calculation to be more robust.
+ https://bugs.webkit.org/show_bug.cgi?id=43777
+
+ Test: websocket/tests/frame-length-overflow.html
+
+ * websockets/WebSocketChannel.cpp:
+ (WebCore::WebSocketChannel::appendToBuffer): len is size_t.
+ - add sanity check for integer wraps.
+ (WebCore::WebSocketChannel::skipBuffer): len is size_t.
+ (WebCore::WebSocketChannel::processBuffer): length is size_t.
+ - add sanity check for integer wraps.
+ * websockets/WebSocketChannel.h: change m_bufferSize and len to size_t.
+
2010-08-10 Eric Seidel <eric at webkit.org>
Reviewed by Adam Barth.
diff --git a/WebCore/websockets/WebSocketChannel.cpp b/WebCore/websockets/WebSocketChannel.cpp
index b8d6e8a..e924b91 100644
--- a/WebCore/websockets/WebSocketChannel.cpp
+++ b/WebCore/websockets/WebSocketChannel.cpp
@@ -198,23 +198,28 @@ void WebSocketChannel::didCancelAuthenticationChallenge(SocketStreamHandle*, con
{
}
-bool WebSocketChannel::appendToBuffer(const char* data, int len)
+bool WebSocketChannel::appendToBuffer(const char* data, size_t len)
{
+ size_t newBufferSize = m_bufferSize + len;
+ if (newBufferSize < m_bufferSize) {
+ LOG(Network, "WebSocket buffer overflow (%lu+%lu)", m_bufferSize, len);
+ return false;
+ }
char* newBuffer = 0;
- if (tryFastMalloc(m_bufferSize + len).getValue(newBuffer)) {
+ if (tryFastMalloc(newBufferSize).getValue(newBuffer)) {
if (m_buffer)
memcpy(newBuffer, m_buffer, m_bufferSize);
memcpy(newBuffer + m_bufferSize, data, len);
fastFree(m_buffer);
m_buffer = newBuffer;
- m_bufferSize += len;
+ m_bufferSize = newBufferSize;
return true;
}
- m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, String::format("WebSocket frame (at %d bytes) is too long.", m_bufferSize + len), 0, m_handshake.clientOrigin());
+ m_context->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, String::format("WebSocket frame (at %lu bytes) is too long.", newBufferSize), 0, m_handshake.clientOrigin());
return false;
}
-void WebSocketChannel::skipBuffer(int len)
+void WebSocketChannel::skipBuffer(size_t len)
{
ASSERT(len <= m_bufferSize);
m_bufferSize -= len;
@@ -268,27 +273,50 @@ bool WebSocketChannel::processBuffer()
unsigned char frameByte = static_cast<unsigned char>(*p++);
if ((frameByte & 0x80) == 0x80) {
- int length = 0;
+ size_t length = 0;
+ bool errorFrame = false;
while (p < end) {
- if (length > std::numeric_limits<int>::max() / 128) {
- LOG(Network, "frame length overflow %d", length);
- skipBuffer(p + length - m_buffer);
- m_client->didReceiveMessageError();
- if (!m_client)
- return false;
- if (!m_closed)
- m_handle->close();
- return false;
+ if (length > std::numeric_limits<size_t>::max() / 128) {
+ LOG(Network, "frame length overflow %lu", length);
+ errorFrame = true;
+ break;
}
- char msgByte = *p;
- length = length * 128 + (msgByte & 0x7f);
+ size_t newLength = length * 128;
+ unsigned char msgByte = static_cast<unsigned char>(*p);
+ unsigned int lengthMsgByte = msgByte & 0x7f;
+ if (newLength > std::numeric_limits<size_t>::max() - lengthMsgByte) {
+ LOG(Network, "frame length overflow %lu+%u", newLength, lengthMsgByte);
+ errorFrame = true;
+ break;
+ }
+ newLength += lengthMsgByte;
+ if (newLength < length) { // sanity check
+ LOG(Network, "frame length integer wrap %lu->%lu", length, newLength);
+ errorFrame = true;
+ break;
+ }
+ length = newLength;
++p;
if (!(msgByte & 0x80))
break;
}
+ if (p + length < p) {
+ LOG(Network, "frame buffer pointer wrap %p+%lu->%p", p, length, p + length);
+ errorFrame = true;
+ }
+ if (errorFrame) {
+ m_client->didReceiveMessageError();
+ if (!m_client)
+ return false;
+ if (!m_closed)
+ m_handle->close();
+ return false;
+ }
+ ASSERT(p + length >= p);
if (p + length < end) {
p += length;
nextFrame = p;
+ ASSERT(nextFrame > m_buffer);
skipBuffer(nextFrame - m_buffer);
m_client->didReceiveMessageError();
return m_buffer;
diff --git a/WebCore/websockets/WebSocketChannel.h b/WebCore/websockets/WebSocketChannel.h
index 893b4c6..06be50e 100644
--- a/WebCore/websockets/WebSocketChannel.h
+++ b/WebCore/websockets/WebSocketChannel.h
@@ -79,8 +79,8 @@ namespace WebCore {
private:
WebSocketChannel(ScriptExecutionContext*, WebSocketChannelClient*, const KURL&, const String& protocol);
- bool appendToBuffer(const char* data, int len);
- void skipBuffer(int len);
+ bool appendToBuffer(const char* data, size_t len);
+ void skipBuffer(size_t len);
bool processBuffer();
void resumeTimerFired(Timer<WebSocketChannel>* timer);
@@ -89,7 +89,7 @@ namespace WebCore {
WebSocketHandshake m_handshake;
RefPtr<SocketStreamHandle> m_handle;
char* m_buffer;
- int m_bufferSize;
+ size_t m_bufferSize;
Timer<WebSocketChannel> m_resumeTimer;
bool m_suspended;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list