From a0007b7ce4e80bb162cbecf59982174fed488f40 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 22 Jul 2008 04:16:14 +0000 Subject: [PATCH] 2396. [bug] Don't set SO_REUSEADDR for randomized ports. [RT #18336] --- CHANGES | 3 +++ bin/dig/dighost.c | 11 ++++++----- bin/named/controlconf.c | 4 ++-- bin/named/interfacemgr.c | 4 ++-- bin/named/lwresd.c | 4 ++-- bin/tests/sig0_test.c | 4 ++-- bin/tests/sock_test.c | 4 ++-- lib/dns/dispatch.c | 10 +++++----- lib/dns/request.c | 6 +++--- lib/dns/resolver.c | 4 ++-- lib/dns/xfrin.c | 4 ++-- lib/isc/include/isc/socket.h | 6 ++++-- lib/isc/unix/socket.c | 7 ++++--- lib/isc/win32/socket.c | 7 ++++--- 14 files changed, 43 insertions(+), 35 deletions(-) diff --git a/CHANGES b/CHANGES index a44e20337b..17ae2e309b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2396. [bug] Don't set SO_REUSEADDR for randomized ports. + [RT #18336] + --- 9.3.5-P1 released --- 2375. [security] Fully randomize UDP query ports to improve diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index f3b0d9954b..a33b19b073 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.221.2.19.2.46 2008/01/17 23:45:26 tbox Exp $ */ +/* $Id: dighost.c,v 1.221.2.19.2.46.4.1 2008/07/22 04:16:13 marka Exp $ */ /* * Notice to programmers: Do not use this code as an example of how to @@ -2047,14 +2047,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); @@ -2101,11 +2101,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 d8a7bcf2fc..286948eca3 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: controlconf.c,v 1.28.2.9.2.13 2008/01/17 23:45:27 tbox Exp $ */ +/* $Id: controlconf.c,v 1.28.2.9.2.13.4.1 2008/07/22 04:16:13 marka Exp $ */ #include @@ -1107,7 +1107,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) result = control_listen(listener); diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c index f3d1d0b88c..48b7ce080d 100644 --- a/bin/named/interfacemgr.c +++ b/bin/named/interfacemgr.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: interfacemgr.c,v 1.59.2.5.8.21 2007/08/28 07:19:08 tbox Exp $ */ +/* $Id: interfacemgr.c,v 1.59.2.5.8.21.4.1 2008/07/22 04:16:13 marka Exp $ */ #include @@ -298,7 +298,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 e48822f711..9ddfd046eb 100644 --- a/bin/named/lwresd.c +++ b/bin/named/lwresd.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: lwresd.c,v 1.37.2.2.2.8 2006/02/28 06:32:53 marka Exp $ */ +/* $Id: lwresd.c,v 1.37.2.2.2.8.14.1 2008/07/22 04:16:13 marka Exp $ */ /* * Main program for the Lightweight Resolver Daemon. @@ -569,7 +569,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/tests/sig0_test.c b/bin/tests/sig0_test.c index 4464d9ddc8..8f5c4ed1ab 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.9.12.8 2007/08/28 07:19:09 tbox Exp $ */ +/* $Id: sig0_test.c,v 1.9.12.8.4.1 2008/07/22 04:16:13 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 0aafee1521..2453ee1bb9 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.47.12.7 2007/08/28 07:19:09 tbox Exp $ */ +/* $Id: sock_test.c,v 1.47.12.7.4.1 2008/07/22 04:16:13 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 207432d5f3..66da0f939d 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dispatch.c,v 1.101.2.6.2.21.4.1 2008/05/22 21:11:15 each Exp $ */ +/* $Id: dispatch.c,v 1.101.2.6.2.21.4.2 2008/07/22 04:16:13 marka Exp $ */ #include @@ -1167,7 +1167,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; @@ -1181,7 +1181,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); @@ -1913,7 +1913,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; @@ -1921,7 +1921,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 69841e5e71..c8074aa59b 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: request.c,v 1.64.2.1.10.12 2007/08/28 07:19:13 tbox Exp $ */ +/* $Id: request.c,v 1.64.2.1.10.12.4.1 2008/07/22 04:16:13 marka Exp $ */ #include @@ -516,11 +516,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 93f10f5dd3..6e78fab3d4 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.218.2.18.4.77.2.1 2008/05/22 21:11:15 each Exp $ */ +/* $Id: resolver.c,v 1.218.2.18.4.77.2.2 2008/07/22 04:16:13 marka Exp $ */ #include @@ -1061,7 +1061,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 432569a4e4..8017352fa0 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrin.c,v 1.124.2.4.2.21 2007/10/31 01:59:03 marka Exp $ */ +/* $Id: xfrin.c,v 1.124.2.4.2.21.4.1 2008/07/22 04:16:14 marka Exp $ */ #include @@ -857,7 +857,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 324a61a19e..2a55804151 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.54.12.7 2007/08/28 07:19:15 tbox Exp $ */ +/* $Id: socket.h,v 1.54.12.7.4.1 2008/07/22 04:16:14 marka Exp $ */ #ifndef ISC_SOCKET_H #define ISC_SOCKET_H 1 @@ -306,7 +306,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'. * @@ -351,6 +351,8 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog); * * 'socket' is a valid, bound TCP socket. * + * \li 'reuseaddr' asks to set SO_REUSEADDR (if the port is not 0). + * Returns: * * ISC_R_SUCCESS diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index 7322abc251..2e8f67f6c1 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.207.2.19.2.35 2008/01/27 02:06:07 marka Exp $ */ +/* $Id: socket.c,v 1.207.2.19.2.35.4.1 2008/07/22 04:16:14 marka Exp $ */ #include @@ -2948,7 +2948,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) { char strbuf[ISC_STRERRORSIZE]; int on = 1; @@ -2963,7 +2963,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__, diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index 79dfe7a098..f2be9b9d31 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.5.2.13.2.24 2007/08/28 07:19:17 tbox Exp $ */ +/* $Id: socket.c,v 1.5.2.13.2.24.4.1 2008/07/22 04:16:14 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 @@ -3257,7 +3257,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; @@ -3273,7 +3273,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__,