Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-7-0]: src/libexec/mail.local Pull up following revision(s) (reque...



details:   https://anonhg.NetBSD.org/src/rev/f6bd35a0f6c4
branches:  netbsd-7-0
changeset: 801200:f6bd35a0f6c4
user:      martin <martin%NetBSD.org@localhost>
date:      Tue Jul 19 14:12:10 2016 +0000

description:
Pull up following revision(s) (requested by shm in ticket #1206):
        libexec/mail.local/mail.local.c: revision 1.27
Fix race condition in deliver(), fix resource leak.

diffstat:

 libexec/mail.local/mail.local.c |  52 +++++++++++++++++++++++++++++-----------
 1 files changed, 38 insertions(+), 14 deletions(-)

diffs (108 lines):

diff -r f68c3aece881 -r f6bd35a0f6c4 libexec/mail.local/mail.local.c
--- a/libexec/mail.local/mail.local.c   Thu Jul 14 18:30:20 2016 +0000
+++ b/libexec/mail.local/mail.local.c   Tue Jul 19 14:12:10 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mail.local.c,v 1.26 2011/08/27 15:40:31 joerg Exp $    */
+/*     $NetBSD: mail.local.c,v 1.26.22.1 2016/07/19 14:12:10 martin Exp $      */
 
 /*-
  * Copyright (c) 1990, 1993, 1994
@@ -36,7 +36,7 @@
 #if 0
 static char sccsid[] = "@(#)mail.local.c       8.22 (Berkeley) 6/21/95";
 #else
-__RCSID("$NetBSD: mail.local.c,v 1.26 2011/08/27 15:40:31 joerg Exp $");
+__RCSID("$NetBSD: mail.local.c,v 1.26.22.1 2016/07/19 14:12:10 martin Exp $");
 #endif
 #endif /* not lint */
 
@@ -169,7 +169,8 @@
        (void)fflush(fp);
        if (ferror(fp))
                logerr(EX_OSERR, "temporary file write error");
-       fd = dup(fd);
+       if ((fd = dup(fd)) == -1) 
+               logerr(EX_OSERR, "dup failed");
        (void)fclose(fp);
        return(fd);
 }
@@ -177,10 +178,10 @@
 static int
 deliver(int fd, char *name, int lockfile)
 {
-       struct stat sb;
+       struct stat sb, nsb;
        struct passwd pwres, *pw;
        char pwbuf[1024];
-       int created, mbfd, nr, nw, off, rval=EX_OK, lfd=-1;
+       int created = 0, mbfd, nr, nw, off, rval=EX_OK, lfd = -1;
        char biffmsg[100], buf[8*1024], path[MAXPATHLEN], lpath[MAXPATHLEN];
        off_t curoff;
 
@@ -210,22 +211,42 @@
                }
        }
 
-       if (!(created = lstat(path, &sb)) &&
+       if ((lstat(path, &sb) != -1) &&
            (sb.st_nlink != 1 || S_ISLNK(sb.st_mode))) {
                logwarn("%s: linked file", path);
                return(EX_OSERR);
        }
        
        if ((mbfd = open(path, O_APPEND|O_WRONLY|O_EXLOCK,
-           S_IRUSR|S_IWUSR)) < 0) {
+           S_IRUSR|S_IWUSR)) != -1) {
+               /* create file */
                if ((mbfd = open(path, O_APPEND|O_CREAT|O_WRONLY|O_EXLOCK,
-                   S_IRUSR|S_IWUSR)) < 0) {
+                   S_IRUSR|S_IWUSR)) != -1) {
                        logwarn("%s: %s", path, strerror(errno));
-                       return(EX_OSERR);
+                       rval = EX_OSERR;
+                       goto bad;
+               }
+               created = 1;
+       } else {
+               /* opened existing file, check for TOCTTOU */
+               if (fstat(mbfd, &nsb) == -1) {
+                       rval = EX_OSERR;
+                       goto bad;
+               }
+
+               /* file is not what we expected */
+               if (nsb.st_ino != sb.st_ino || nsb.st_dev != sb.st_dev) {
+                       rval = EX_OSERR;
+                       goto bad;
                }
        }
 
-       curoff = lseek(mbfd, 0, SEEK_END);
+       if ((curoff = lseek(mbfd, 0, SEEK_END)) == (off_t)-1) {
+               logwarn("%s: %s", path, strerror(errno));
+               rval = EX_OSERR;
+               goto bad;
+       }
+
        (void)snprintf(biffmsg, sizeof biffmsg, "%s@%lld\n", name,
            (long long)curoff);
        if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
@@ -259,11 +280,14 @@
                        close(lfd);
                }
        }
-       if (created) 
-               (void)fchown(mbfd, pw->pw_uid, pw->pw_gid);
 
-       (void)fsync(mbfd);              /* Don't wait for update. */
-       (void)close(mbfd);              /* Implicit unlock. */
+       if (mbfd >= 0) {
+               if (created) 
+                       (void)fchown(mbfd, pw->pw_uid, pw->pw_gid);
+
+               (void)fsync(mbfd);              /* Don't wait for update. */
+               (void)close(mbfd);              /* Implicit unlock. */
+       }
 
        if (rval == EX_OK)
                notifybiff(biffmsg);



Home | Main Index | Thread Index | Old Index