Module: kamailio Branch: 5.0 Commit: fd96ab480515713e4a390376f38bc09aa28e93b4 URL: https://github.com/kamailio/kamailio/commit/fd96ab480515713e4a390376f38bc09a...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@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/fd96ab480515713e4a390376f38bc09a... Patch: https://github.com/kamailio/kamailio/commit/fd96ab480515713e4a390376f38bc09a...
---
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;