From 572759b47d85126054c1c8b3113e1f0224a313a4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Jun 2011 09:56:06 +0200 Subject: [PATCH 1/2] s3:nmbd_packets: make sure create_listen_fdset() returns initialized data (bug #8276) Fix bug #7949 (DoS in Winbind and smbd with many file descriptors open) (commit feb3fcd0fa4bda0967b881315595d7702f4d1752) changed the bahavior, so that we skipped some sockets. This should work for v3-5-test. metze --- source3/nmbd/nmbd_packets.c | 44 +++++++++++++++++++++++++----------------- 1 files changed, 26 insertions(+), 18 deletions(-) diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c index 0eafb2c..e53eebb 100644 --- a/source3/nmbd/nmbd_packets.c +++ b/source3/nmbd/nmbd_packets.c @@ -1729,19 +1729,23 @@ only use %d.\n", count, FD_SETSIZE)); for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { if (subrec->nmb_sock < 0 || subrec->nmb_sock >= FD_SETSIZE) { /* We have to ignore sockets outside FD_SETSIZE. */ - continue; + sock_array[num++] = -1; + } else { + FD_SET(subrec->nmb_sock,pset); + sock_array[num++] = subrec->nmb_sock; + *maxfd = MAX( *maxfd, subrec->nmb_sock); } - FD_SET(subrec->nmb_sock,pset); - sock_array[num++] = subrec->nmb_sock; - *maxfd = MAX( *maxfd, subrec->nmb_sock); if (subrec->nmb_bcast < 0 || subrec->nmb_bcast >= FD_SETSIZE) { /* We have to ignore sockets outside FD_SETSIZE. */ - continue; + sock_array[num++] = -1; + } else { + sock_array[num++] = subrec->nmb_bcast; + if (subrec->nmb_bcast != -1) { + FD_SET(subrec->nmb_bcast,pset); + *maxfd = MAX( *maxfd, subrec->nmb_bcast); + } } - sock_array[num++] = subrec->nmb_bcast; - FD_SET(subrec->nmb_bcast,pset); - *maxfd = MAX( *maxfd, subrec->nmb_bcast); } /* Add in the lp_socket_address() interface on 138. */ @@ -1761,23 +1765,27 @@ only use %d.\n", count, FD_SETSIZE)); for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { if (subrec->dgram_sock < 0 || subrec->dgram_sock >= FD_SETSIZE) { /* We have to ignore sockets outside FD_SETSIZE. */ - continue; + sock_array[num++] = -1; + } else { + FD_SET(subrec->dgram_sock,pset); + sock_array[num++] = subrec->dgram_sock; + *maxfd = MAX( *maxfd, subrec->dgram_sock); } - FD_SET(subrec->dgram_sock,pset); - sock_array[num++] = subrec->dgram_sock; - *maxfd = MAX( *maxfd, subrec->dgram_sock); if (subrec->dgram_bcast < 0 || subrec->dgram_bcast >= FD_SETSIZE) { /* We have to ignore sockets outside FD_SETSIZE. */ - continue; - } - sock_array[num++] = subrec->dgram_bcast; - if (subrec->dgram_bcast != -1) { - FD_SET(subrec->dgram_bcast,pset); - *maxfd = MAX( *maxfd, subrec->dgram_bcast); + sock_array[num++] = -1; + } else { + sock_array[num++] = subrec->dgram_bcast; + if (subrec->dgram_bcast != -1) { + FD_SET(subrec->dgram_bcast,pset); + *maxfd = MAX( *maxfd, subrec->dgram_bcast); + } } } + SMB_ASSERT(count == num); + *listen_number = count; SAFE_FREE(*ppset); -- 1.7.4.1 From 164670e768d9d6a22a9d66c3c80a7ff8ae80d75b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Jun 2011 10:09:56 +0200 Subject: [PATCH 2/2] s3:nmbd_subnetdb: close all sockets attached to a subnet in close_subnet() (bug #8276) metze (cherry picked from commit 75e9f2110876137a57632d223248ac51dbfc4569) --- source3/nmbd/nmbd_subnetdb.c | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-) diff --git a/source3/nmbd/nmbd_subnetdb.c b/source3/nmbd/nmbd_subnetdb.c index 703e229..48dbe66 100644 --- a/source3/nmbd/nmbd_subnetdb.c +++ b/source3/nmbd/nmbd_subnetdb.c @@ -55,13 +55,21 @@ yet and it may be in use by a response record void close_subnet(struct subnet_record *subrec) { + if (subrec->nmb_sock != -1) { + close(subrec->nmb_sock); + subrec->nmb_sock = -1; + } + if (subrec->nmb_bcast != -1) { + close(subrec->nmb_bcast); + subrec->nmb_bcast = -1; + } if (subrec->dgram_sock != -1) { close(subrec->dgram_sock); subrec->dgram_sock = -1; } - if (subrec->nmb_sock != -1) { - close(subrec->nmb_sock); - subrec->nmb_sock = -1; + if (subrec->dgram_bcast != -1) { + close(subrec->dgram_bcast); + subrec->dgram_bcast = -1; } DLIST_REMOVE(subnetlist, subrec); -- 1.7.4.1