dovecot: Calculate needed fd count better. Make sure we have one...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Sep 15 17:02:38 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/1b21dfee7bd7
changeset: 6396:1b21dfee7bd7
user: Timo Sirainen <tss at iki.fi>
date: Sat Sep 15 16:58:18 2007 +0300
description:
Calculate needed fd count better. Make sure we have one unused fd available
when exec()ing so it doesn't fail.
diffstat:
1 file changed, 14 insertions(+), 8 deletions(-)
src/master/login-process.c | 22 ++++++++++++++--------
diffs (50 lines):
diff -r 1622e332c8ae -r 1b21dfee7bd7 src/master/login-process.c
--- a/src/master/login-process.c Sat Sep 15 16:57:11 2007 +0300
+++ b/src/master/login-process.c Sat Sep 15 16:58:18 2007 +0300
@@ -589,8 +589,8 @@ static pid_t create_login_process(struct
const char *prefix;
pid_t pid;
ARRAY_TYPE(dup2) dups;
- unsigned int i, listen_count = 0, ssl_listen_count = 0;
- int fd[2], log_fd, cur_fd;
+ unsigned int i, fd_limit, listen_count = 0, ssl_listen_count = 0;
+ int fd[2], log_fd, cur_fd, tmp_fd;
if (group->set->login_uid == 0)
i_fatal("Login process must not run as root");
@@ -664,8 +664,8 @@ static pid_t create_login_process(struct
i_fatal("Failed to dup2() fds");
/* don't close any of these */
- while (cur_fd >= 0)
- fd_close_on_exec(cur_fd--, FALSE);
+ for (tmp_fd = 0; tmp_fd <= cur_fd; tmp_fd++)
+ fd_close_on_exec(tmp_fd, FALSE);
(void)close(fd[0]);
(void)close(fd[1]);
@@ -684,14 +684,20 @@ static pid_t create_login_process(struct
}
restrict_process_size(group->set->login_process_size, (unsigned int)-1);
- if (group->set->login_process_per_connection)
- restrict_fd_limit(16 + 2);
- else
- restrict_fd_limit(16 + 2*group->set->login_max_connections);
+ fd_limit = 16 + listen_count + ssl_listen_count +
+ 2 * (group->set->login_process_per_connection ? 1 :
+ group->set->login_max_connections);
+ restrict_fd_limit(fd_limit);
/* make sure we don't leak syslog fd, but do it last so that
any errors above will be logged */
closelog();
+
+ /* execv() needs at least one file descriptor. we might have all fds
+ up to fd_limit used already, so close one we don't care about.
+ either it succeeds or fails with EBADF, doesn't matter. */
+ i_assert(fd_limit > (unsigned int)cur_fd+1);
+ (void)close(cur_fd+1);
client_process_exec(group->set->login_executable, "");
i_fatal_status(FATAL_EXEC, "execv(%s) failed: %m",
More information about the dovecot-cvs
mailing list