Mercurial > dovecot > original-hg > dovecot-1.2
changeset 727:8dd8ebe6bcac HEAD
We use close-on-exec flag now to make sure that master process closes the
fds when executing other processes.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 01 Dec 2002 17:39:20 +0200 |
parents | d60c6c65d1ca |
children | 883cda17d175 |
files | src/auth/main.c src/imap/main.c src/lib/Makefile.am src/lib/fd-close-on-exec.c src/lib/fd-close-on-exec.h src/login/main.c src/master/auth-process.c src/master/auth-process.h src/master/login-process.c src/master/login-process.h src/master/main.c |
diffstat | 11 files changed, 90 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/main.c Sun Dec 01 17:37:19 2002 +0200 +++ b/src/auth/main.c Sun Dec 01 17:39:20 2002 +0200 @@ -5,6 +5,7 @@ #include "network.h" #include "lib-signals.h" #include "restrict-access.h" +#include "fd-close-on-exec.h" #include "randgen.h" #include "auth.h" #include "cookie.h" @@ -93,6 +94,9 @@ int main(int argc __attr_unused__, char *argv[] __attr_unused__) { +#ifdef DEBUG + fd_debug_verify_leaks(4, 1024); +#endif /* NOTE: we start rooted, so keep the code minimal until restrict_access_by_env() is called */ lib_init();
--- a/src/imap/main.c Sun Dec 01 17:37:19 2002 +0200 +++ b/src/imap/main.c Sun Dec 01 17:39:20 2002 +0200 @@ -5,6 +5,7 @@ #include "lib-signals.h" #include "rawlog.h" #include "restrict-access.h" +#include "fd-close-on-exec.h" #include <stdlib.h> #include <syslog.h> @@ -104,6 +105,9 @@ int main(int argc, char *argv[]) { +#ifdef DEBUG + fd_debug_verify_leaks(3, 1024); +#endif /* NOTE: we start rooted, so keep the code minimal until restrict_access_by_env() is called */ lib_init();
--- a/src/lib/Makefile.am Sun Dec 01 17:37:19 2002 +0200 +++ b/src/lib/Makefile.am Sun Dec 01 17:39:20 2002 +0200 @@ -7,6 +7,7 @@ data-stack.c \ env-util.c \ failures.c \ + fd-close-on-exec.c \ fdpass.c \ file-lock.c \ file-set-size.c \ @@ -54,6 +55,7 @@ data-stack.h \ env-util.h \ failures.h \ + fd-close-on-exec.h \ fdpass.h \ file-lock.h \ file-set-size.h \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/fd-close-on-exec.c Sun Dec 01 17:39:20 2002 +0200 @@ -0,0 +1,50 @@ +/* + Copyright (c) 2002 Timo Sirainen + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "lib.h" +#include "fd-close-on-exec.h" + +#include <unistd.h> +#include <fcntl.h> + +void fd_close_on_exec(int fd, int set) +{ + int flags; + + flags = fcntl(fd, F_GETFD, 0); + if (flags < 0) + i_fatal("fcntl(F_GETFD) failed: %m"); + + flags = set ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC); + if (fcntl(fd, F_SETFD, flags) < 0) + i_fatal("fcntl(F_SETFD) failed: %m"); +} + +void fd_debug_verify_leaks(int first_fd, int last_fd) +{ + while (first_fd < last_fd) { + if (fcntl(first_fd, F_GETFD, 0) != -1 || errno != EBADF) + i_fatal("Leaked file descriptor: %d", first_fd); + first_fd++; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/fd-close-on-exec.h Sun Dec 01 17:39:20 2002 +0200 @@ -0,0 +1,10 @@ +#ifndef __FD_CLOSE_ON_EXEC_H +#define __FD_CLOSE_ON_EXEC_H + +/* Change close-on-exec flag of fd. */ +void fd_close_on_exec(int fd, int set); + +/* Verify that fds in given range don't exist. */ +void fd_debug_verify_leaks(int first_fd, int last_fd); + +#endif
--- a/src/login/main.c Sun Dec 01 17:37:19 2002 +0200 +++ b/src/login/main.c Sun Dec 01 17:39:20 2002 +0200 @@ -4,6 +4,7 @@ #include "ioloop.h" #include "lib-signals.h" #include "restrict-access.h" +#include "fd-close-on-exec.h" #include "auth-connection.h" #include "master.h" #include "client.h" @@ -192,6 +193,9 @@ int main(int argc __attr_unused__, char *argv[] __attr_unused__) { +#ifdef DEBUG + fd_debug_verify_leaks(3, 1024); +#endif /* NOTE: we start rooted, so keep the code minimal until restrict_access_by_env() is called */ lib_init();
--- a/src/master/auth-process.c Sun Dec 01 17:37:19 2002 +0200 +++ b/src/master/auth-process.c Sun Dec 01 17:39:20 2002 +0200 @@ -3,6 +3,7 @@ #include "common.h" #include "ioloop.h" #include "env-util.h" +#include "fd-close-on-exec.h" #include "network.h" #include "obuffer.h" #include "restrict-access.h" @@ -171,13 +172,12 @@ const char *path; struct passwd *pwd; pid_t pid; - int fd[2], listen_fd; + int fd[2], listen_fd, i; if ((pwd = getpwnam(config->user)) == NULL) i_fatal("Auth user doesn't exist: %s", config->user); - /* create communication to process with a socket pair - FIXME: pipe() would work as well, would it be better? */ + /* create communication to process with a socket pair */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) { i_error("socketpair() failed: %m"); return -1; @@ -193,6 +193,7 @@ if (pid != 0) { /* master */ + fd_close_on_exec(fd[0], TRUE); auth_process_new(pid, fd[0], config->name); (void)close(fd[1]); return pid; @@ -235,6 +236,9 @@ (void)close(listen_fd); } + for (i = 0; i <= 2; i++) + fd_close_on_exec(i, FALSE); + /* setup access environment - needs to be done after clean_child_process() since it clears environment */ restrict_access_set_env(config->user, pwd->pw_uid, pwd->pw_gid, @@ -300,14 +304,6 @@ return count; } -void auth_processes_cleanup(void) -{ - AuthProcess *p; - - for (p = processes; p != NULL; p = p->next) - (void)close(p->fd); -} - void auth_processes_destroy_all(void) { AuthProcess *next;
--- a/src/master/auth-process.h Sun Dec 01 17:37:19 2002 +0200 +++ b/src/master/auth-process.h Sun Dec 01 17:39:20 2002 +0200 @@ -16,7 +16,6 @@ AuthCallback callback, void *context); /* Close any fds used by auth processes */ -void auth_processes_cleanup(void); void auth_processes_destroy_all(void); void auth_processes_init(void);
--- a/src/master/login-process.c Sun Dec 01 17:37:19 2002 +0200 +++ b/src/master/login-process.c Sun Dec 01 17:39:20 2002 +0200 @@ -5,6 +5,7 @@ #include "network.h" #include "obuffer.h" #include "fdpass.h" +#include "fd-close-on-exec.h" #include "env-util.h" #include "restrict-access.h" #include "restrict-process-size.h" @@ -266,6 +267,7 @@ if (pid != 0) { /* master */ + fd_close_on_exec(fd[0], TRUE); login_process_new(pid, fd[0]); (void)close(fd[1]); return pid; @@ -274,14 +276,17 @@ /* move communication handle */ if (dup2(fd[1], LOGIN_MASTER_SOCKET_FD) < 0) i_fatal("login: dup2() failed: %m"); + fd_close_on_exec(LOGIN_MASTER_SOCKET_FD, FALSE); /* move the listen handle */ if (dup2(imap_fd, LOGIN_IMAP_LISTEN_FD) < 0) i_fatal("login: dup2() failed: %m"); + fd_close_on_exec(LOGIN_IMAP_LISTEN_FD, FALSE); /* move the SSL listen handle */ if (dup2(imaps_fd, LOGIN_IMAPS_LISTEN_FD) < 0) i_fatal("login: dup2() failed: %m"); + fd_close_on_exec(LOGIN_IMAPS_LISTEN_FD, FALSE); /* imap_fd and imaps_fd are closed by clean_child_process() */ @@ -340,19 +345,6 @@ wanted_processes_count = 0; } -static void login_hash_cleanup(void *key __attr_unused__, void *value, - void *context __attr_unused__) -{ - LoginProcess *p = value; - - (void)close(p->fd); -} - -void login_processes_cleanup(void) -{ - hash_foreach(processes, login_hash_cleanup, NULL); -} - static void login_hash_destroy(void *key __attr_unused__, void *value, void *context __attr_unused__) {
--- a/src/master/login-process.h Sun Dec 01 17:37:19 2002 +0200 +++ b/src/master/login-process.h Sun Dec 01 17:39:20 2002 +0200 @@ -2,7 +2,6 @@ #define __CHILD_LOGIN_H void login_process_abormal_exit(pid_t pid); -void login_processes_cleanup(void); void login_processes_destroy_all(void); void login_processes_init(void);
--- a/src/master/main.c Sun Dec 01 17:37:19 2002 +0200 +++ b/src/master/main.c Sun Dec 01 17:39:20 2002 +0200 @@ -5,6 +5,7 @@ #include "lib-signals.h" #include "network.h" #include "env-util.h" +#include "fd-close-on-exec.h" #include "auth-process.h" #include "login-process.h" @@ -56,14 +57,6 @@ if (set_log_timestamp != NULL) env_put(t_strconcat("IMAP_LOGSTAMP=", set_log_timestamp, NULL)); - (void)close(null_fd); - (void)close(imap_fd); - (void)close(imaps_fd); - - /* close fds for auth/login processes */ - login_processes_cleanup(); - auth_processes_cleanup(); - closelog(); } @@ -156,11 +149,13 @@ null_fd = open("/dev/null", O_RDONLY); if (null_fd == -1) i_fatal("Can't open /dev/null: %m"); + fd_close_on_exec(null_fd, TRUE); imap_fd = set_imap_port == 0 ? dup(null_fd) : net_listen(imap_ip, &set_imap_port); if (imap_fd == -1) i_fatal("listen(%d) failed: %m", set_imap_port); + fd_close_on_exec(imap_fd, TRUE); #ifdef HAVE_SSL imaps_fd = set_ssl_cert_file == NULL || *set_ssl_cert_file == '\0' || @@ -172,6 +167,7 @@ #endif if (imaps_fd == -1) i_fatal("listen(%d) failed: %m", set_imaps_port); + fd_close_on_exec(imaps_fd, TRUE); } static void main_init(void)