Skip to content

Commit 4b8bead

Browse files
committed
Add a check for invalid frame length. Credit to Dane (4cad@silvertoque).
Closes dhbaird#85.
1 parent 112cb81 commit 4b8bead

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

easywsclient.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,13 @@ class _RealWebSocket : public easywsclient::WebSocket
172172
socket_t sockfd;
173173
readyStateValues readyState;
174174
bool useMask;
175+
bool isRxBad;
175176

176-
_RealWebSocket(socket_t sockfd, bool useMask) : sockfd(sockfd), readyState(OPEN), useMask(useMask) {
177+
_RealWebSocket(socket_t sockfd, bool useMask)
178+
: sockfd(sockfd)
179+
, readyState(OPEN)
180+
, useMask(useMask)
181+
, isRxBad(false) {
177182
}
178183

179184
readyStateValues getReadyState() const {
@@ -264,6 +269,9 @@ class _RealWebSocket : public easywsclient::WebSocket
264269

265270
virtual void _dispatchBinary(BytesCallback_Imp & callable) {
266271
// TODO: consider acquiring a lock on rxbuf...
272+
if (isRxBad) {
273+
return;
274+
}
267275
while (true) {
268276
wsheader_type ws;
269277
if (rxbuf.size() < 2) { return; /* Need at least 2 */ }
@@ -296,6 +304,20 @@ class _RealWebSocket : public easywsclient::WebSocket
296304
ws.N |= ((uint64_t) data[8]) << 8;
297305
ws.N |= ((uint64_t) data[9]) << 0;
298306
i = 10;
307+
if (ws.N & 0x8000000000000000ull) {
308+
// https://tools.ietf.org/html/rfc6455 writes the "the most
309+
// significant bit MUST be 0."
310+
//
311+
// We can't drop the frame, because (1) we don't we don't
312+
// know how much data to skip over to find the next header,
313+
// and (2) this would be an impractically long length, even
314+
// if it were valid. So just close() and return immediately
315+
// for now.
316+
isRxBad = true;
317+
fprintf(stderr, "ERROR: Frame has invalid frame length. Closing.\n");
318+
close();
319+
return;
320+
}
299321
}
300322
if (ws.mask) {
301323
ws.masking_key[0] = ((uint8_t) data[i+0]) << 0;
@@ -309,6 +331,9 @@ class _RealWebSocket : public easywsclient::WebSocket
309331
ws.masking_key[2] = 0;
310332
ws.masking_key[3] = 0;
311333
}
334+
335+
// Note: The checks above should hopefully ensure this addition
336+
// cannot overflow:
312337
if (rxbuf.size() < ws.header_size+ws.N) { return; /* Need: ws.header_size+ws.N - rxbuf.size() */ }
313338

314339
// We got a whole message, now do something with it:

0 commit comments

Comments
 (0)