Add a check for invalid frame length. Credit to Dane (4cad@silvertoque).
Closes #85.
This commit is contained in:
+26
-1
@@ -172,8 +172,13 @@ class _RealWebSocket : public easywsclient::WebSocket
|
|||||||
socket_t sockfd;
|
socket_t sockfd;
|
||||||
readyStateValues readyState;
|
readyStateValues readyState;
|
||||||
bool useMask;
|
bool useMask;
|
||||||
|
bool isRxBad;
|
||||||
|
|
||||||
_RealWebSocket(socket_t sockfd, bool useMask) : sockfd(sockfd), readyState(OPEN), useMask(useMask) {
|
_RealWebSocket(socket_t sockfd, bool useMask)
|
||||||
|
: sockfd(sockfd)
|
||||||
|
, readyState(OPEN)
|
||||||
|
, useMask(useMask)
|
||||||
|
, isRxBad(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
readyStateValues getReadyState() const {
|
readyStateValues getReadyState() const {
|
||||||
@@ -264,6 +269,9 @@ class _RealWebSocket : public easywsclient::WebSocket
|
|||||||
|
|
||||||
virtual void _dispatchBinary(BytesCallback_Imp & callable) {
|
virtual void _dispatchBinary(BytesCallback_Imp & callable) {
|
||||||
// TODO: consider acquiring a lock on rxbuf...
|
// TODO: consider acquiring a lock on rxbuf...
|
||||||
|
if (isRxBad) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
wsheader_type ws;
|
wsheader_type ws;
|
||||||
if (rxbuf.size() < 2) { return; /* Need at least 2 */ }
|
if (rxbuf.size() < 2) { return; /* Need at least 2 */ }
|
||||||
@@ -296,6 +304,20 @@ class _RealWebSocket : public easywsclient::WebSocket
|
|||||||
ws.N |= ((uint64_t) data[8]) << 8;
|
ws.N |= ((uint64_t) data[8]) << 8;
|
||||||
ws.N |= ((uint64_t) data[9]) << 0;
|
ws.N |= ((uint64_t) data[9]) << 0;
|
||||||
i = 10;
|
i = 10;
|
||||||
|
if (ws.N & 0x8000000000000000ull) {
|
||||||
|
// https://tools.ietf.org/html/rfc6455 writes the "the most
|
||||||
|
// significant bit MUST be 0."
|
||||||
|
//
|
||||||
|
// We can't drop the frame, because (1) we don't we don't
|
||||||
|
// know how much data to skip over to find the next header,
|
||||||
|
// and (2) this would be an impractically long length, even
|
||||||
|
// if it were valid. So just close() and return immediately
|
||||||
|
// for now.
|
||||||
|
isRxBad = true;
|
||||||
|
fprintf(stderr, "ERROR: Frame has invalid frame length. Closing.\n");
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ws.mask) {
|
if (ws.mask) {
|
||||||
ws.masking_key[0] = ((uint8_t) data[i+0]) << 0;
|
ws.masking_key[0] = ((uint8_t) data[i+0]) << 0;
|
||||||
@@ -309,6 +331,9 @@ class _RealWebSocket : public easywsclient::WebSocket
|
|||||||
ws.masking_key[2] = 0;
|
ws.masking_key[2] = 0;
|
||||||
ws.masking_key[3] = 0;
|
ws.masking_key[3] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: The checks above should hopefully ensure this addition
|
||||||
|
// cannot overflow:
|
||||||
if (rxbuf.size() < ws.header_size+ws.N) { return; /* Need: ws.header_size+ws.N - rxbuf.size() */ }
|
if (rxbuf.size() < ws.header_size+ws.N) { return; /* Need: ws.header_size+ws.N - rxbuf.size() */ }
|
||||||
|
|
||||||
// We got a whole message, now do something with it:
|
// We got a whole message, now do something with it:
|
||||||
|
|||||||
Reference in New Issue
Block a user