瀏覽代碼

Merge branch 'advisory-fix-1' CVE-2020-26262

Mészáros Mihály 4 年之前
父節點
當前提交
abfe1fd08d
共有 3 個文件被更改,包括 30 次插入2 次删除
  1. 27 2
      src/client/ns_turn_ioaddr.c
  2. 1 0
      src/client/ns_turn_ioaddr.h
  3. 2 0
      src/server/ns_turn_server.c

+ 27 - 2
src/client/ns_turn_ioaddr.c

@@ -483,9 +483,9 @@ int ioa_addr_is_loopback(ioa_addr *addr)
 			return (u[0] == 127);
 		} else if(addr->ss.sa_family == AF_INET6) {
 			const uint8_t *u = ((const uint8_t*)&(addr->s6.sin6_addr));
-			if(u[7] == 1) {
+			if(u[15] == 1) {
 				int i;
-				for(i=0;i<7;++i) {
+				for(i=0;i<15;++i) {
 					if(u[i])
 						return 0;
 				}
@@ -496,6 +496,31 @@ int ioa_addr_is_loopback(ioa_addr *addr)
 	return 0;
 }
 
+/*
+To avoid a vulnerability this function checks whether the addr is in 0.0.0.0/8 or ::/128.
+Source from (INADDR_ANY) 0.0.0.0/32 and (in6addr_any) ::/128 routed to loopback on Linux systems for old BSD backward compatibility.
+https://github.com/torvalds/linux/blob/a2f5ea9e314ba6778f885c805c921e9362ec0420/net/ipv6/tcp_ipv6.c#L182
+To avoid any trouble we match the whole 0.0.0.0/8 that defined in RFC6890 as local network "this".
+*/
+int ioa_addr_is_zero(ioa_addr *addr)
+{
+	if(addr) {
+		if(addr->ss.sa_family == AF_INET) {
+			const uint8_t *u = ((const uint8_t*)&(addr->s4.sin_addr));
+			return (u[0] == 0);
+		} else if(addr->ss.sa_family == AF_INET6) {
+			const uint8_t *u = ((const uint8_t*)&(addr->s6.sin6_addr));
+			int i;
+			for(i=0;i<=15;++i) {
+				if(u[i])
+					return 0;
+			}
+			return 1;
+		}
+	}
+	return 0;
+}
+
 /////// Map "public" address to "private" address //////////////
 
 // Must be called only in a single-threaded context,

+ 1 - 0
src/client/ns_turn_ioaddr.h

@@ -89,6 +89,7 @@ void ioa_addr_range_cpy(ioa_addr_range* dest, const ioa_addr_range* src);
 
 int ioa_addr_is_multicast(ioa_addr *a);
 int ioa_addr_is_loopback(ioa_addr *addr);
+int ioa_addr_is_zero(ioa_addr *addr);
 
 /////// Map "public" address to "private" address //////////////
 

+ 2 - 0
src/server/ns_turn_server.c

@@ -273,6 +273,8 @@ static int good_peer_addr(turn_turnserver *server, const char* realm, ioa_addr *
 			return 0;
 		if( !*(server->allow_loopback_peers) && ioa_addr_is_loopback(peer_addr))
 			return 0;
+		if (ioa_addr_is_zero(peer_addr))
+			return 0;
 
 		{
 			int i;