Mercurial > dovecot > core-2.2
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); }