Module: kamailio
Branch: 5.0
Commit: fd96ab480515713e4a390376f38bc09aa28e93b4
URL:
https://github.com/kamailio/kamailio/commit/fd96ab480515713e4a390376f38bc09…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: 2017-09-15T14:46:20+02:00
core: tcp_read_ws() - safety checks for very large advetised lenght
- use unsigned for lenght to avoid going negative on large read values
(cherry picked from commit 35ee3a4b0357820bf31b3aa68323dcb7df267e94)
---
Modified: src/core/tcp_read.c
---
Diff:
https://github.com/kamailio/kamailio/commit/fd96ab480515713e4a390376f38bc09…
Patch:
https://github.com/kamailio/kamailio/commit/fd96ab480515713e4a390376f38bc09…
---
diff --git a/src/core/tcp_read.c b/src/core/tcp_read.c
index b2a9e9fbe8..7014353c62 100644
--- a/src/core/tcp_read.c
+++ b/src/core/tcp_read.c
@@ -1079,8 +1079,8 @@ int msrp_process_msg(char* tcpbuf, unsigned int len,
#ifdef READ_WS
static int tcp_read_ws(struct tcp_connection *c, int* read_flags)
{
- int bytes, size, pos, mask_present;
- unsigned int len;
+ int bytes;
+ uint32_t size, pos, mask_present, len;
char *p;
struct tcp_req *r;
@@ -1137,22 +1137,27 @@ static int tcp_read_ws(struct tcp_connection *c, int* read_flags)
/* Work out real length */
if (len == 126)
{
+ /* 2 bytes store the payload size */
if (size < pos + 2)
goto skip;
- len = ((p[pos + 0] & 0xff) << 8)
- | ((p[pos + 1] & 0xff) << 0);
+ len = ((p[pos + 0] & 0xff) << 8) | ((p[pos + 1] & 0xff) << 0);
pos += 2;
- }
- else if (len == 127)
- {
- if (size < pos + 8)
+ } else if (len == 127) {
+ /* 8 bytes store the payload size */
+ if (size < pos + 8) {
goto skip;
+ }
/* Only decoding the last four bytes of the length...
This limits the size of WebSocket messages that can be
handled to 2^32 - which should be plenty for SIP! */
- len = ((p[pos + 4] & 0xff) << 24)
+ if((p[pos] & 0xff)!=0 || (p[pos + 1] & 0xff)!=0
+ || (p[pos + 2] & 0xff)!=0 || (p[pos + 3] & 0xff)!=0) {
+ LM_WARN("advertised lenght is too large (more than 2^32)\n");
+ goto skip;
+ }
+ len = ((p[pos + 4] & 0xff) << 24)
| ((p[pos + 5] & 0xff) << 16)
| ((p[pos + 6] & 0xff) << 8)
| ((p[pos + 7] & 0xff) << 0);
@@ -1167,6 +1172,12 @@ static int tcp_read_ws(struct tcp_connection *c, int* read_flags)
pos += 4;
}
+ /* check if advertised lenght fits in read buffer */
+ if(len>=r->b_size) {
+ LM_WARN("advertised lenght (%u) greater than buffer size (%u)\n",
+ len, r->b_size);
+ goto skip;
+ }
/* Now check the whole message has been received */
if (size < pos + len)
goto skip;