From: W.C.A. Wijngaards Date: Thu, 12 Nov 2020 11:27:41 +0000 (+0100) Subject: - Fix to connect() to UDP destinations, default turned on, X-Git-Tag: release-1.13.0rc1~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=26aa550bd246079b26366627fecbbe7d6e30dabd;p=thirdparty%2Funbound.git - Fix to connect() to UDP destinations, default turned on, this lowers vulnerability to ICMP side channels. --- diff --git a/services/outside_network.c b/services/outside_network.c index 41a1d83f1..cef76053c 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -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;