]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix to connect() to UDP destinations, default turned on,
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 12 Nov 2020 11:27:41 +0000 (12:27 +0100)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 12 Nov 2020 11:27:41 +0000 (12:27 +0100)
  this lowers vulnerability to ICMP side channels.

services/outside_network.c

index 41a1d83f1454b79a9822dc1f3b6d56f6da2b344a..cef76053c58d33d7c689e9dfdbffd69739d2aca8 100644 (file)
@@ -1115,13 +1115,23 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
                my_if = ub_random_max(outnet->rnd, num_if);
                pif = &ifs[my_if];
 #ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
-               my_port = ub_random_max(outnet->rnd, pif->avail_total);
-               if(my_port < pif->inuse) {
-                       /* port already open */
-                       pend->pc = pif->out[my_port];
-                       verbose(VERB_ALGO, "using UDP if=%d port=%d", 
-                               my_if, pend->pc->number);
-                       break;
+               if(1) {
+                       /* if we connect() we cannot reuse fds for a port */
+                       if(pif->inuse >= pif->avail_total) {
+                               log_err("failed to find an open port, drop msg");
+                               return 0;
+                       }
+                       my_port = pif->inuse + ub_random_max(outnet->rnd,
+                               pif->avail_total - pif->inuse);
+               } else  {
+                       my_port = ub_random_max(outnet->rnd, pif->avail_total);
+                       if(my_port < pif->inuse) {
+                               /* port already open */
+                               pend->pc = pif->out[my_port];
+                               verbose(VERB_ALGO, "using UDP if=%d port=%d",
+                                       my_if, pend->pc->number);
+                               break;
+                       }
                }
                /* try to open new port, if fails, loop to try again */
                log_assert(pif->inuse < pif->maxout);
@@ -1138,6 +1148,17 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
                if(fd != -1) {
                        verbose(VERB_ALGO, "opened UDP if=%d port=%d", 
                                my_if, portno);
+                       if(1) {
+                               /* connect() to the destination */
+                               if(connect(fd, (struct sockaddr*)&pend->addr,
+                                       pend->addrlen) < 0) {
+                                       log_err_addr("udp connect failed",
+                                               strerror(errno), &pend->addr,
+                                               pend->addrlen);
+                                       sock_close(fd);
+                                       return 0;
+                               }
+                       }
                        /* grab fd */
                        pend->pc = outnet->unused_fds;
                        outnet->unused_fds = pend->pc->next;