view files/patch-src_client_ns__turn__msg.c @ 15:18dd9a5710c6

Append only to log files rather to override them (fixes #416). commit cfdb99dc72fc4104eba9dffaf93d707d3780ca2a
author Franz Glasner <fzglas.hg@dom66.de>
date Sat, 28 Mar 2020 15:54:45 +0100
parents c7cf16351c81
children
line wrap: on
line source

--- src/client/ns_turn_msg.c.orig	2019-03-02 21:06:19 UTC
+++ src/client/ns_turn_msg.c
@@ -360,7 +360,13 @@ int stun_get_command_message_len_str(const u08bits* bu
 {
 	if (len < STUN_HEADER_LENGTH)
 		return -1;
-	return (int) (nswap16(((const u16bits*)(buf))[1]) + STUN_HEADER_LENGTH);
+	/* Validate the size the buffer claims to be */
+	size_t bufLen = (size_t) (nswap16(((const u16bits*)(buf))[1]) + STUN_HEADER_LENGTH);
+	if (bufLen > len) {
+		return -1;
+	}
+
+	return bufLen;
 }
 
 static int stun_set_command_message_len_str(u08bits* buf, int len) {
@@ -1351,10 +1357,34 @@ stun_attr_ref stun_attr_get_first_by_type_str(const u0
   return NULL;
 }
 
+static stun_attr_ref stun_attr_check_valid(stun_attr_ref attr, size_t remaining) {
+
+  if(remaining >= 4) {
+    /* Read the size of the attribute */
+    size_t attrlen = stun_attr_get_len(attr);
+    remaining -= 4;
+
+    /* Round to boundary */
+    uint16_t rem4 = ((uint16_t)attrlen) & 0x0003;
+    if(rem4) {
+      attrlen = attrlen+4-rem4;
+    }
+
+    /* Check that there's enough space remaining */
+    if(attrlen <= remaining) {
+      return attr;
+    }
+  }
+
+  return NULL;
+}
+
 stun_attr_ref stun_attr_get_first_str(const u08bits* buf, size_t len) {
 
-  if(stun_get_command_message_len_str(buf,len)>STUN_HEADER_LENGTH) {
-    return (stun_attr_ref)(buf+STUN_HEADER_LENGTH);
+  int bufLen = stun_get_command_message_len_str(buf,len);
+  if(bufLen > STUN_HEADER_LENGTH) {
+    stun_attr_ref attr = (stun_attr_ref)(buf+STUN_HEADER_LENGTH);
+    return stun_attr_check_valid(attr, bufLen - STUN_HEADER_LENGTH);
   }
 
   return NULL;
@@ -1370,8 +1400,11 @@ stun_attr_ref stun_attr_get_next_str(const u08bits* bu
     if(rem4) {
       attrlen = attrlen+4-(int)rem4;
     }
-    const u08bits* attr_end=(const u08bits*)prev+4+attrlen;
-    if(attr_end<end) return attr_end;
+    /* Note the order here: operations on attrlen are untrusted as they may overflow */
+    if(attrlen < end - (const u08bits*)prev - 4) {
+      const u08bits* attr_end=(const u08bits*)prev+4+attrlen;
+      return stun_attr_check_valid(attr_end, end - attr_end);
+    }
     return NULL;
   }
 }