dovecot-2.0: fs-sis: Fixed a race condition between comparing fi...

dovecot at dovecot.org dovecot at dovecot.org
Sat Oct 2 14:33:55 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/8e511be90b4b
changeset: 12235:8e511be90b4b
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Jul 22 20:01:55 2010 +0100
description:
fs-sis: Fixed a race condition between comparing files' equality and link()ing

diffstat:

 src/lib-fs/fs-sis.c |  18 +++++++++++++++++-
 1 files changed, 17 insertions(+), 1 deletions(-)

diffs (35 lines):

diff -r 21ceba48445d -r 8e511be90b4b src/lib-fs/fs-sis.c
--- a/src/lib-fs/fs-sis.c	Wed Jul 21 21:08:18 2010 +0100
+++ b/src/lib-fs/fs-sis.c	Thu Jul 22 20:01:55 2010 +0100
@@ -168,14 +168,30 @@
 static bool fs_sis_try_link(struct sis_fs_file *file)
 {
 	const char *path = fs_file_path(&file->file);
+	const struct stat *st;
+	struct stat st2;
+
+	st = i_stream_stat(file->hash_input, FALSE);
 
 	/* we can use the existing file */
 	if (fs_link(file->super->fs, file->hash_path, path) < 0) {
 		if (errno != ENOENT && errno != EMLINK)
-			i_error("%s", fs_last_error(file->super->fs));
+			i_error("fs-sis: %s", fs_last_error(file->super->fs));
 		/* failed to use link(), continue as if it hadn't been equal */
 		return FALSE;
 	}
+	if (fs_stat(file->super->fs, path, &st2) < 0) {
+		i_error("fs-sis: %s", fs_last_error(file->super->fs));
+		if (fs_unlink(file->super->fs, path) < 0)
+			i_error("fs-sis: %s", fs_last_error(file->super->fs));
+		return FALSE;
+	}
+	if (st->st_ino != st2.st_ino) {
+		/* the hashes/ file was already replaced with something else */
+		if (fs_unlink(file->super->fs, path) < 0)
+			i_error("fs-sis: %s", fs_last_error(file->super->fs));
+		return FALSE;
+	}
 	return TRUE;
 }
 


More information about the dovecot-cvs mailing list