X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/f1e894f37fb99398f7447220925a915bd031491a..bf83d8d38bc9a0f3b3574eb6641b619e68d7a796:/src/src/exim_lock.c diff --git a/src/src/exim_lock.c b/src/src/exim_lock.c index 9e2f43373..0c60ce107 100644 --- a/src/src/exim_lock.c +++ b/src/src/exim_lock.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/exim_lock.c,v 1.3 2005/06/27 14:29:43 ph10 Exp $ */ +/* $Cambridge: exim/src/src/exim_lock.c,v 1.4 2010/05/29 12:11:48 pdp Exp $ */ /* A program to lock a file exactly as Exim would, for investigation of interlocking problems. @@ -310,7 +310,8 @@ if (use_lockfile) for (j = 0; j < lock_retries; j++) { int sleep_before_retry = TRUE; - struct stat statbuf, ostatbuf; + struct stat statbuf, ostatbuf, lstatbuf, statbuf2; + int mbx_tmp_oflags; /* Try to build a lock file if so configured */ @@ -431,7 +432,11 @@ for (j = 0; j < lock_retries; j++) } } - md = open(tempname, O_RDWR | O_CREAT, 0600); + mbx_tmp_oflags = O_RDWR | O_CREAT; +#ifdef O_NOFOLLOW + mbx_tmp_oflags |= O_NOFOLLOW; +#endif + md = open(tempname, mbx_tmp_oflags, 0600); if (md < 0) { printf("exim_lock: failed to create mbx lock file %s: %s\n", @@ -439,6 +444,30 @@ for (j = 0; j < lock_retries; j++) goto CLEAN_UP; } + /* security fixes from 2010-05 */ + if (lstat(tempname, &lstatbuf) < 0) + { + printf("exim_lock: failed to lstat(%s) after opening it: %s\n", + tempname, strerror(errno)); + goto CLEAN_UP; + } + if (fstat(md, &statbuf2) < 0) + { + printf("exim_lock: failed to fstat() open fd of \"%s\": %s\n", + tempname, strerror(errno)); + goto CLEAN_UP; + } + if ((statbuf2.st_nlink > 1) || + (lstatbuf.st_nlink > 1) || + (!S_ISREG(lstatbuf.st_mode)) || + (lstatbuf.st_dev != statbuf2.st_dev) || + (lstatbuf.st_ino != statbuf2.st_ino)) + { + printf("exim_lock: race condition exploited against us when " + "locking \"%s\"\n", tempname); + goto CLEAN_UP; + } + (void)chmod(tempname, 0600); if (apply_lock(md, F_WRLCK, use_fcntl, lock_fcntl_timeout, use_flock,