changeset 22075:baa85b2663b5

lib-master: Replace listeners with /dev/null in SIGQUIT instead of closing This should be somewhat safer.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Wed, 24 May 2017 17:19:36 +0300
parents 2553f62ea247
children 6b68ff970c9e
files src/lib-master/master-service-private.h src/lib-master/master-service.c
diffstat 2 files changed, 10 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-master/master-service-private.h	Mon May 22 10:13:21 2017 +0300
+++ b/src/lib-master/master-service-private.h	Wed May 24 17:19:36 2017 +0300
@@ -15,6 +15,7 @@
 	bool haproxy;
 
 	/* state */
+	bool closed;
 	int fd;	
 	struct io *io;
 };
--- a/src/lib-master/master-service.c	Mon May 22 10:13:21 2017 +0300
+++ b/src/lib-master/master-service.c	Wed May 24 17:19:36 2017 +0300
@@ -95,13 +95,17 @@
 	   that don't have an io, but this shouldn't be a big problem. If there
 	   is an active io, the service is unlikely to be unresposive for
 	   longer periods of time, so the listener gets closed soon enough via
-	   master_status_error(). */
+	   master_status_error().
+
+	   For extra safety we don't actually close() the fd, but instead
+	   replace it with /dev/null. This way it won't be replaced with some
+	   other new fd and attempted to be used in unexpected ways. */
 	for (unsigned int i = 0; i < service->socket_count; i++) {
 		if (service->listeners[i].fd != -1 &&
 		    service->listeners[i].io == NULL) {
-			if (close(service->listeners[i].fd) < 0)
-				lib_signals_syscall_error("signal: close(listener) failed: ");
-			service->listeners[i].fd = -1;
+			if (dup2(dev_null_fd, service->listeners[i].fd) < 0)
+				lib_signals_syscall_error("signal: dup2(/dev/null, listener) failed: ");
+			service->listeners[i].closed = TRUE;
 		}
 	}
 }
@@ -1007,7 +1011,7 @@
 	for (i = 0; i < service->socket_count; i++) {
 		struct master_service_listener *l = &service->listeners[i];
 
-		if (l->io == NULL && l->fd != -1) {
+		if (l->io == NULL && l->fd != -1 && !l->closed) {
 			l->io = io_add(MASTER_LISTEN_FD_FIRST + i, IO_READ,
 				       master_service_listen, l);
 		}