]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix #1283: Unsafe usage of atoi() while parsing the configuration
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Mon, 12 May 2025 12:57:42 +0000 (14:57 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Mon, 12 May 2025 12:57:42 +0000 (14:57 +0200)
  file.

doc/Changelog
testcode/unitmain.c
util/net_help.c

index e86095860f248edd19154a8a5666627eea22c177..8d4a93ff65ffbd7abfea28755655733c4d3924aa 100644 (file)
@@ -3,6 +3,10 @@
          broken auth zones that include unsigned out of zone (above apex)
          data. Could lead to hang while trying to prove a wildcard answer.
 
+12 May 2025: Wouter
+       - Fix #1283: Unsafe usage of atoi() while parsing the configuration
+         file.
+
 9 May 2025: Wouter
        - Fix #1281: forward-zone "name: ." conflicts with auth-zone "name: ."
          in 1.23.0, but worked in 1.22.0.
index 334c1af93033a93d15051f853b0ab537b8038751..07c016d7ba7431a3960716cfdd6fb9627faab037 100644 (file)
@@ -205,6 +205,8 @@ net_test(void)
                unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\000", 16) == 0);
                addr_mask((struct sockaddr_storage*)&a6, l6, 64);
                unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000", 16) == 0);
+               /* Check that negative value in net is not problematic. */
+               addr_mask((struct sockaddr_storage*)&a6, l6, -100);
                addr_mask((struct sockaddr_storage*)&a6, l6, 0);
                unit_assert(memcmp(&a6.sin6_addr, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16) == 0);
        }
@@ -266,6 +268,28 @@ net_test(void)
                                (struct sockaddr_storage*)&b6, i, l6) == i);
                }
        }
+       /* test netblockstrtoaddr */
+       unit_show_func("util/net_help.c", "netblockstrtoaddr");
+       if(1) {
+               struct sockaddr_storage a;
+               socklen_t alen = 0;
+               int net = 0, res;
+               char astr[128];
+               memset(&a, 0, sizeof(a));
+
+               res = netblockstrtoaddr("1.2.3.0/24", 53, &a, &alen, &net);
+               unit_assert(res!=0 && net == 24);
+               addr_to_str(&a, alen, astr, sizeof(astr));
+               unit_assert(strcmp(astr, "1.2.3.0") == 0);
+               unit_assert(ntohs(((struct sockaddr_in*)&a)->sin_port)==53);
+
+               res = netblockstrtoaddr("2001:DB8:33:44::/64", 53,
+                       &a, &alen, &net);
+               unit_assert(res!=0 && net == 64);
+               addr_to_str(&a, alen, astr, sizeof(astr));
+               unit_assert(strcmp(astr, "2001:db8:33:44::") == 0);
+               unit_assert(ntohs(((struct sockaddr_in6*)&a)->sin6_port)==53);
+       }
        /* test sockaddr_cmp_addr */
        unit_show_func("util/net_help.c", "sockaddr_cmp_addr");
        if(1) {
index 8eca6b757ca8ccd3a15f6cc50a792fc4aed4e8c4..a50737dd8497d8bce3a86b86020d05a001cc5aef 100644 (file)
@@ -317,6 +317,11 @@ int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
                        log_err("cannot parse netblock: '%s'", str);
                        return 0;
                }
+               if(*net < 0) {
+                       log_err("netblock value %d is negative in: '%s'",
+                               *net, str);
+                       return 0;
+               }
                strlcpy(buf, str, sizeof(buf));
                s = strchr(buf, '/');
                if(s) *s = 0;
@@ -430,6 +435,8 @@ int netblockdnametoaddr(uint8_t* dname, size_t dnamelen,
        *net = atoi(buff);
        if(*net == 0 && strcmp(buff, "0") != 0)
                return 0;
+       if(*net < 0)
+               return 0;
        dname += nlablen;
        dname++;
        if(!ipdnametoaddr(dname, dnamelen-1-nlablen, addr, addrlen, af))
@@ -797,7 +804,7 @@ addr_mask(struct sockaddr_storage* addr, socklen_t len, int net)
                s = (uint8_t*)&((struct sockaddr_in*)addr)->sin_addr;
                max = 32;
        }
-       if(net >= max)
+       if(net >= max || net < 0)
                return;
        for(i=net/8+1; i<max/8; i++) {
                s[i] = 0;