From: Mark Andrews Date: Tue, 22 Jul 2008 04:26:23 +0000 (+0000) Subject: 2396. [bug] Don't set SO_REUSEADDR for randomized ports. X-Git-Tag: v9.4.2-P2~24 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=47a1536eb6327bd42a902ab79dfae76b825055b2;p=thirdparty%2Fbind9.git 2396. [bug] Don't set SO_REUSEADDR for randomized ports. [RT #18336] --- diff --git a/CHANGES b/CHANGES index 43d2bd7af22..b49b05c9cde 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2396. [bug] Don't set SO_REUSEADDR for randomized ports. + [RT #18336] + --- 9.4.2-P1 released --- 2375. [security] Fully randomize UDP query ports to improve diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 6e7c16be108..ac166e9633f 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.259.18.43 2007/08/28 07:19:55 tbox Exp $ */ +/* $Id: dighost.c,v 1.259.18.43.10.1 2008/07/22 04:26:22 marka Exp $ */ /*! \file * \note @@ -2217,14 +2217,14 @@ send_tcp_connect(dig_query_t *query) { sockcount++; debug("sockcount=%d", sockcount); if (specified_source) - result = isc_socket_bind(query->sock, &bind_address); + result = isc_socket_bind(query->sock, &bind_address, 1); else { if ((isc_sockaddr_pf(&query->sockaddr) == AF_INET) && have_ipv4) isc_sockaddr_any(&bind_any); else isc_sockaddr_any6(&bind_any); - result = isc_socket_bind(query->sock, &bind_any); + result = isc_socket_bind(query->sock, &bind_any, 0); } check_result(result, "isc_socket_bind"); bringup_timer(query, TCP_TIMEOUT); @@ -2271,11 +2271,12 @@ send_udp(dig_query_t *query) { sockcount++; debug("sockcount=%d", sockcount); if (specified_source) { - result = isc_socket_bind(query->sock, &bind_address); + result = isc_socket_bind(query->sock, + &bind_address, 1); } else { isc_sockaddr_anyofpf(&bind_any, isc_sockaddr_pf(&query->sockaddr)); - result = isc_socket_bind(query->sock, &bind_any); + result = isc_socket_bind(query->sock, &bind_any, 0); } check_result(result, "isc_socket_bind"); diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c index 3e364469e6d..0d58ee3973b 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: controlconf.c,v 1.40.18.10 2006/12/07 04:53:02 marka Exp $ */ +/* $Id: controlconf.c,v 1.40.18.10.40.1 2008/07/22 04:26:22 marka Exp $ */ /*! \file */ @@ -1152,7 +1152,7 @@ add_listener(ns_controls_t *cp, controllistener_t **listenerp, if (result == ISC_R_SUCCESS) result = isc_socket_bind(listener->sock, - &listener->address); + &listener->address, 1); if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) { listener->perm = cfg_obj_asuint32(cfg_tuple_get(control, diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c index db410310147..6b7924214db 100644 --- a/bin/named/interfacemgr.c +++ b/bin/named/interfacemgr.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: interfacemgr.c,v 1.76.18.8 2006/07/20 01:10:30 marka Exp $ */ +/* $Id: interfacemgr.c,v 1.76.18.8.44.1 2008/07/22 04:26:22 marka Exp $ */ /*! \file */ @@ -307,7 +307,7 @@ ns_interface_accepttcp(ns_interface_t *ifp) { #ifndef ISC_ALLOW_MAPPED isc_socket_ipv6only(ifp->tcpsocket, ISC_TRUE); #endif - result = isc_socket_bind(ifp->tcpsocket, &ifp->addr); + result = isc_socket_bind(ifp->tcpsocket, &ifp->addr, 1); if (result != ISC_R_SUCCESS) { isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, "binding TCP socket: %s", diff --git a/bin/named/lwresd.c b/bin/named/lwresd.c index a1073fa4bbf..a8a07e5a455 100644 --- a/bin/named/lwresd.c +++ b/bin/named/lwresd.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: lwresd.c,v 1.46.18.7 2006/03/02 00:37:21 marka Exp $ */ +/* $Id: lwresd.c,v 1.46.18.7.52.1 2008/07/22 04:26:22 marka Exp $ */ /*! \file * \brief @@ -576,7 +576,7 @@ listener_bind(ns_lwreslistener_t *listener, isc_sockaddr_t *address) { return (result); } - result = isc_socket_bind(sock, &listener->address); + result = isc_socket_bind(sock, &listener->address, 1); if (result != ISC_R_SUCCESS) { char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(&listener->address, socktext, diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c index 8fd0d8e1e2c..312c1bc5a76 100644 --- a/bin/rndc/rndc.c +++ b/bin/rndc/rndc.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rndc.c,v 1.96.18.17 2006/08/04 03:03:41 marka Exp $ */ +/* $Id: rndc.c,v 1.96.18.17.42.1 2008/07/22 04:26:22 marka Exp $ */ /*! \file */ @@ -400,10 +400,10 @@ rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task) { DO("create socket", isc_socket_create(socketmgr, pf, type, &sock)); switch (isc_sockaddr_pf(addr)) { case AF_INET: - DO("bind socket", isc_socket_bind(sock, &local4)); + DO("bind socket", isc_socket_bind(sock, &local4, 1)); break; case AF_INET6: - DO("bind socket", isc_socket_bind(sock, &local6)); + DO("bind socket", isc_socket_bind(sock, &local6, 1)); break; default: break; diff --git a/bin/tests/sig0_test.c b/bin/tests/sig0_test.c index 128ade490b4..a3d9a6a3685 100644 --- a/bin/tests/sig0_test.c +++ b/bin/tests/sig0_test.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sig0_test.c,v 1.11.18.2 2005/03/17 03:57:08 marka Exp $ */ +/* $Id: sig0_test.c,v 1.11.18.2.52.1 2008/07/22 04:26:22 marka Exp $ */ #include @@ -189,7 +189,7 @@ buildquery(void) { isc_buffer_usedregion(&qbuffer, &r); isc_sockaddr_any(&sa); - result = isc_socket_bind(s, &sa); + result = isc_socket_bind(s, &sa, 0); CHECK("isc_socket_bind", result); result = isc_socket_sendto(s, &r, task1, senddone, NULL, &address, NULL); diff --git a/bin/tests/sock_test.c b/bin/tests/sock_test.c index e879503fda1..ffb1c5d7ab4 100644 --- a/bin/tests/sock_test.c +++ b/bin/tests/sock_test.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sock_test.c,v 1.49.18.1 2004/08/28 06:17:30 marka Exp $ */ +/* $Id: sock_test.c,v 1.49.18.1.52.1 2008/07/22 04:26:22 marka Exp $ */ #include @@ -321,7 +321,7 @@ main(int argc, char *argv[]) { } RUNTIME_CHECK(isc_socket_create(socketmgr, pf, isc_sockettype_tcp, &so1) == ISC_R_SUCCESS); - result = isc_socket_bind(so1, &sockaddr); + result = isc_socket_bind(so1, &sockaddr, 1); RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(isc_socket_listen(so1, 0) == ISC_R_SUCCESS); diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 4da89ca20b2..7460b7ce961 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dispatch.c,v 1.116.18.19.12.1 2008/05/22 21:28:06 each Exp $ */ +/* $Id: dispatch.c,v 1.116.18.19.12.2 2008/07/22 04:26:22 marka Exp $ */ /*! \file */ @@ -1172,7 +1172,7 @@ destroy_mgr(dns_dispatchmgr_t **mgrp) { static isc_result_t create_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local, - isc_socket_t **sockp) + int reuseaddr, isc_socket_t **sockp) { isc_socket_t *sock; isc_result_t result; @@ -1186,7 +1186,7 @@ create_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local, #ifndef ISC_ALLOW_MAPPED isc_socket_ipv6only(sock, ISC_TRUE); #endif - result = isc_socket_bind(sock, local); + result = isc_socket_bind(sock, local, reuseaddr); if (result != ISC_R_SUCCESS) { isc_socket_detach(&sock); return (result); @@ -1917,7 +1917,7 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, attributes &= ~DNS_DISPATCHATTR_RANDOMPORT; goto getsocket; } - result = create_socket(sockmgr, &localaddr_bound, &sock); + result = create_socket(sockmgr, &localaddr_bound, 0, &sock); if (result == ISC_R_ADDRINUSE) { if (++k == 1024) attributes &= ~DNS_DISPATCHATTR_RANDOMPORT; @@ -1925,7 +1925,7 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, } localport = prt; } else - result = create_socket(sockmgr, localaddr, &sock); + result = create_socket(sockmgr, localaddr, 1, &sock); if (result != ISC_R_SUCCESS) goto deallocate_dispatch; if ((attributes & DNS_DISPATCHATTR_RANDOMPORT) == 0 && diff --git a/lib/dns/request.c b/lib/dns/request.c index be8f93d6b84..66b5c7a02fd 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: request.c,v 1.72.18.5 2006/08/21 00:40:53 marka Exp $ */ +/* $Id: request.c,v 1.72.18.5.42.1 2008/07/22 04:26:22 marka Exp $ */ /*! \file */ @@ -518,11 +518,11 @@ create_tcp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr, if (srcaddr == NULL) { isc_sockaddr_anyofpf(&bind_any, isc_sockaddr_pf(destaddr)); - result = isc_socket_bind(socket, &bind_any); + result = isc_socket_bind(socket, &bind_any, 0); } else { src = *srcaddr; isc_sockaddr_setport(&src, 0); - result = isc_socket_bind(socket, &src); + result = isc_socket_bind(socket, &src, 0); } if (result != ISC_R_SUCCESS) goto cleanup; diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 03f4a94c256..2d456818861 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.284.18.66.8.1 2008/05/22 21:28:06 each Exp $ */ +/* $Id: resolver.c,v 1.284.18.66.8.2 2008/07/22 04:26:22 marka Exp $ */ /*! \file */ @@ -1123,7 +1123,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, goto cleanup_query; #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT - result = isc_socket_bind(query->tcpsocket, &addr); + result = isc_socket_bind(query->tcpsocket, &addr, 0); if (result != ISC_R_SUCCESS) goto cleanup_socket; #endif diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index dd7801d4f46..cdfc0ececfd 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrin.c,v 1.135.18.16 2007/10/31 01:59:47 marka Exp $ */ +/* $Id: xfrin.c,v 1.135.18.16.10.1 2008/07/22 04:26:23 marka Exp $ */ /*! \file */ @@ -862,7 +862,7 @@ xfrin_start(dns_xfrin_ctx_t *xfr) { isc_sockettype_tcp, &xfr->socket)); #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT - CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr)); + CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr, 1)); #endif CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task, xfrin_connect_done, xfr)); diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h index ccc49f53ca3..0bd0022babe 100644 --- a/lib/isc/include/isc/socket.h +++ b/lib/isc/include/isc/socket.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.h,v 1.57.18.6 2006/06/07 00:29:45 marka Exp $ */ +/* $Id: socket.h,v 1.57.18.6.46.1 2008/07/22 04:26:23 marka Exp $ */ #ifndef ISC_SOCKET_H #define ISC_SOCKET_H 1 @@ -312,7 +312,7 @@ isc_socket_detach(isc_socket_t **socketp); */ isc_result_t -isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *addressp); +isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *addressp, int reuseaddr); /*%< * Bind 'socket' to '*addressp'. * @@ -322,6 +322,8 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *addressp); * * \li 'addressp' points to a valid isc_sockaddr. * + * \li 'reuseaddr' asks to set SO_REUSEADDR (if the port is not 0). + * Returns: * * \li ISC_R_SUCCESS diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index e0b902167e8..ec06c045a0f 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.c,v 1.237.18.29 2007/08/28 07:20:06 tbox Exp $ */ +/* $Id: socket.c,v 1.237.18.29.10.1 2008/07/22 04:26:23 marka Exp $ */ /*! \file */ @@ -3165,7 +3165,7 @@ isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm, } isc_result_t -isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) { +isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr, int reuseaddr) { char strbuf[ISC_STRERRORSIZE]; int on = 1; @@ -3184,7 +3184,8 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) { if (sock->pf == AF_UNIX) goto bind_socket; #endif - if (isc_sockaddr_getport(sockaddr) != (in_port_t)0 && + if (reuseaddr && + isc_sockaddr_getport(sockaddr) != (in_port_t)0 && setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)) < 0) { UNEXPECTED_ERROR(__FILE__, __LINE__, diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index 73ac0acb4ec..b68b1b004f8 100644 --- a/lib/isc/win32/socket.c +++ b/lib/isc/win32/socket.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.c,v 1.30.18.20 2007/08/28 07:20:06 tbox Exp $ */ +/* $Id: socket.c,v 1.30.18.20.12.1 2008/07/22 04:26:23 marka Exp $ */ /* This code has been rewritten to take advantage of Windows Sockets * I/O Completion Ports and Events. I/O Completion Ports is ONLY @@ -3283,7 +3283,7 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, } isc_result_t -isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) { +isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr, int reuseaddr) { int bind_errno; char strbuf[ISC_STRERRORSIZE]; int on = 1; @@ -3299,7 +3299,8 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) { /* * Only set SO_REUSEADDR when we want a specific port. */ - if (isc_sockaddr_getport(sockaddr) != (in_port_t)0 && + if (reuseaddr && + isc_sockaddr_getport(sockaddr) != (in_port_t)0 && setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)) < 0) { UNEXPECTED_ERROR(__FILE__, __LINE__,