From f0802d0abbd74d4a9355bac967f9b9e3236cb53c Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 24 May 2017 17:19:36 +0300 Subject: [PATCH] lib-master: Replace listeners with /dev/null in SIGQUIT instead of closing This should be somewhat safer. --- src/lib-master/master-service-private.h | 1 + src/lib-master/master-service.c | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/lib-master/master-service-private.h b/src/lib-master/master-service-private.h index 7c9a820f1e..b585e38c56 100644 --- a/src/lib-master/master-service-private.h +++ b/src/lib-master/master-service-private.h @@ -15,6 +15,7 @@ struct master_service_listener { bool haproxy; /* state */ + bool closed; int fd; struct io *io; }; diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c index b37cfc5f8b..b5e92f9101 100644 --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -95,13 +95,17 @@ static void sig_close_listeners(const siginfo_t *si ATTR_UNUSED, void *context) 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 @@ void master_service_io_listeners_add(struct master_service *service) 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); } -- 2.47.3