[dovecot-cvs] dovecot/src/master mail-process.c, 1.96.2.19, 1.96.2.20
tss at dovecot.org
tss at dovecot.org
Thu Mar 22 00:52:19 EET 2007
Update of /var/lib/cvs/dovecot/src/master
In directory talvi:/tmp/cvs-serv25089
Modified Files:
Tag: branch_1_0
mail-process.c
Log Message:
Use alarm() to make sure that chdir() returns in 30 seconds (NFS..). Also if
chdir() failed, we could have used wrong errno in the checks.
Index: mail-process.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/master/mail-process.c,v
retrieving revision 1.96.2.19
retrieving revision 1.96.2.20
diff -u -d -r1.96.2.19 -r1.96.2.20
--- mail-process.c 21 Mar 2007 20:31:11 -0000 1.96.2.19
+++ mail-process.c 21 Mar 2007 22:52:17 -0000 1.96.2.20
@@ -24,6 +24,12 @@
# include <sys/resource.h>
#endif
+/* Timeout chdir() completely after this many seconds */
+#define CHDIR_TIMEOUT 30
+/* Give a warning about chdir() taking a while if it took longer than this
+ many seconds to finish. */
+#define CHDIR_WARN_SECS 10
+
static unsigned int mail_process_count = 0;
static bool validate_uid_gid(struct settings *set, uid_t uid, gid_t gid,
@@ -431,8 +437,8 @@
uid_t uid;
gid_t gid;
array_t ARRAY_DEFINE(extra_args, const char *);
- unsigned int i, count;
- int ret, log_fd, nice;
+ unsigned int i, count, left;
+ int ret, log_fd, nice, chdir_errno;
bool home_given, nfs_check;
/* FIXME: per-group? */
@@ -604,7 +610,14 @@
if (seteuid(uid) < 0)
i_fatal("seteuid(%s) failed: %m", dec2str(uid));
}
+
+ alarm(CHDIR_TIMEOUT);
ret = chdir(full_home_dir);
+ chdir_errno = errno;
+ if ((left = alarm(0)) < CHDIR_TIMEOUT - CHDIR_WARN_SECS) {
+ i_warning("chdir(%s) blocked for %u secs",
+ full_home_dir, CHDIR_TIMEOUT - left);
+ }
/* Change UID back. No need to change GID back, it doesn't
really matter. */
@@ -615,8 +628,9 @@
trying to chroot anywhere, fallback to /tmp as the mails
could be stored elsewhere. The ENOTDIR check is mostly for
/dev/null home directory. */
- if (ret < 0 && ((errno != ENOENT && errno != ENOTDIR) ||
- *chroot_dir != '\0')) {
+ if (ret < 0 && (*chroot_dir != '\0' ||
+ !(ENOTFOUND(chdir_errno) ||
+ chdir_errno == EINTR))) {
i_fatal("chdir(%s) failed with uid %s: %m",
full_home_dir, dec2str(uid));
}
More information about the dovecot-cvs
mailing list