[sr-dev] git:master:35ee3a4b: core: tcp_read_ws() - safety checks for very large advetised lenght

Daniel-Constantin Mierla miconda at gmail.com
Fri Sep 15 09:28:32 CEST 2017


Module: kamailio
Branch: master
Commit: 35ee3a4b0357820bf31b3aa68323dcb7df267e94
URL: https://github.com/kamailio/kamailio/commit/35ee3a4b0357820bf31b3aa68323dcb7df267e94

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date: 2017-09-15T09:00:18+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

---

Modified: src/core/tcp_read.c

---

Diff:  https://github.com/kamailio/kamailio/commit/35ee3a4b0357820bf31b3aa68323dcb7df267e94.diff
Patch: https://github.com/kamailio/kamailio/commit/35ee3a4b0357820bf31b3aa68323dcb7df267e94.patch

---

diff --git a/src/core/tcp_read.c b/src/core/tcp_read.c
index f786fb2f6f..77a86854e8 100644
--- a/src/core/tcp_read.c
+++ b/src/core/tcp_read.c
@@ -1083,8 +1083,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;
 
@@ -1141,22 +1141,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);
@@ -1171,6 +1176,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;




More information about the sr-dev mailing list