CVS commit: src/libexec/mail.local

2023-09-06 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Wed Sep  6 22:08:38 UTC 2023

Modified Files:
src/libexec/mail.local: mail.local.c

Log Message:
use the correct constant


To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/libexec/mail.local/mail.local.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/libexec/mail.local

2023-09-06 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Wed Sep  6 22:08:38 UTC 2023

Modified Files:
src/libexec/mail.local: mail.local.c

Log Message:
use the correct constant


To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/libexec/mail.local/mail.local.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/libexec/mail.local/mail.local.c
diff -u src/libexec/mail.local/mail.local.c:1.32 src/libexec/mail.local/mail.local.c:1.33
--- src/libexec/mail.local/mail.local.c:1.32	Wed Sep  6 18:08:06 2023
+++ src/libexec/mail.local/mail.local.c	Wed Sep  6 18:08:38 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: mail.local.c,v 1.32 2023/09/06 22:08:06 christos Exp $	*/
+/*	$NetBSD: mail.local.c,v 1.33 2023/09/06 22:08:38 christos Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993, 1994
@@ -36,7 +36,7 @@ __COPYRIGHT("@(#) Copyright (c) 1990, 19
 #if 0
 static char sccsid[] = "@(#)mail.local.c	8.22 (Berkeley) 6/21/95";
 #else
-__RCSID("$NetBSD: mail.local.c,v 1.32 2023/09/06 22:08:06 christos Exp $");
+__RCSID("$NetBSD: mail.local.c,v 1.33 2023/09/06 22:08:38 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -197,7 +197,7 @@ deliver(int fd, char *name, int lockfile
 	struct stat sb, nsb;
 	struct passwd pwres, *pw;
 	char pwbuf[1024];
-	int created = 0, mbfd = -1, nr, nw, off, rval = EX_ERR, lfd = -1;
+	int created = 0, mbfd = -1, nr, nw, off, rval = EX_OSERR, lfd = -1;
 	char biffmsg[100], buf[8*1024], path[MAXPATHLEN], lpath[MAXPATHLEN];
 	off_t curoff;
 



CVS commit: src/libexec/mail.local

2023-09-06 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Wed Sep  6 22:08:06 UTC 2023

Modified Files:
src/libexec/mail.local: mail.local.c

Log Message:
fix merge botch


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/libexec/mail.local/mail.local.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/libexec/mail.local/mail.local.c
diff -u src/libexec/mail.local/mail.local.c:1.31 src/libexec/mail.local/mail.local.c:1.32
--- src/libexec/mail.local/mail.local.c:1.31	Wed Sep  6 16:16:04 2023
+++ src/libexec/mail.local/mail.local.c	Wed Sep  6 18:08:06 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: mail.local.c,v 1.31 2023/09/06 20:16:04 christos Exp $	*/
+/*	$NetBSD: mail.local.c,v 1.32 2023/09/06 22:08:06 christos Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993, 1994
@@ -36,7 +36,7 @@ __COPYRIGHT("@(#) Copyright (c) 1990, 19
 #if 0
 static char sccsid[] = "@(#)mail.local.c	8.22 (Berkeley) 6/21/95";
 #else
-__RCSID("$NetBSD: mail.local.c,v 1.31 2023/09/06 20:16:04 christos Exp $");
+__RCSID("$NetBSD: mail.local.c,v 1.32 2023/09/06 22:08:06 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -197,7 +197,7 @@ deliver(int fd, char *name, int lockfile
 	struct stat sb, nsb;
 	struct passwd pwres, *pw;
 	char pwbuf[1024];
-	int created = 0, mbfd = -1, nr, nw, off, rval=EX_OK, lfd = -1;
+	int created = 0, mbfd = -1, nr, nw, off, rval = EX_ERR, lfd = -1;
 	char biffmsg[100], buf[8*1024], path[MAXPATHLEN], lpath[MAXPATHLEN];
 	off_t curoff;
 



CVS commit: src/libexec/mail.local

2023-09-06 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Wed Sep  6 22:08:06 UTC 2023

Modified Files:
src/libexec/mail.local: mail.local.c

Log Message:
fix merge botch


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/libexec/mail.local/mail.local.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/libexec/mail.local

2023-09-06 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Wed Sep  6 20:16:05 UTC 2023

Modified Files:
src/libexec/mail.local: mail.local.c

Log Message:
KNF, clarify/provide warning messages, set rval to fail initially and only
set to success once everything works.


To generate a diff of this commit:
cvs rdiff -u -r1.30 -r1.31 src/libexec/mail.local/mail.local.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/libexec/mail.local/mail.local.c
diff -u src/libexec/mail.local/mail.local.c:1.30 src/libexec/mail.local/mail.local.c:1.31
--- src/libexec/mail.local/mail.local.c:1.30	Wed Sep  6 04:12:09 2023
+++ src/libexec/mail.local/mail.local.c	Wed Sep  6 16:16:04 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: mail.local.c,v 1.30 2023/09/06 08:12:09 shm Exp $	*/
+/*	$NetBSD: mail.local.c,v 1.31 2023/09/06 20:16:04 christos Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993, 1994
@@ -36,7 +36,7 @@ __COPYRIGHT("@(#) Copyright (c) 1990, 19
 #if 0
 static char sccsid[] = "@(#)mail.local.c	8.22 (Berkeley) 6/21/95";
 #else
-__RCSID("$NetBSD: mail.local.c,v 1.30 2023/09/06 08:12:09 shm Exp $");
+__RCSID("$NetBSD: mail.local.c,v 1.31 2023/09/06 20:16:04 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -125,7 +125,7 @@ main(int argc, char *argv[])
 		if (eval == EX_OK && rval != EX_OK)
 			eval = rval;
 	}
-	exit (eval);
+	return eval;
 }
 
 static int
@@ -173,7 +173,7 @@ store(const char *from)
 	if ((fd = dup(fd)) == -1) 
 		logerr(EX_OSERR, "dup failed");
 	(void)fclose(fp);
-	return(fd);
+	return fd;
 }
 
 static bool
@@ -207,11 +207,11 @@ deliver(int fd, char *name, int lockfile
 	 */
 	if ((getpwnam_r(name, , pwbuf, sizeof(pwbuf), )) != 0) {
 		logwarn("unable to find user %s: %s", name, strerror(errno));
-		return(EX_TEMPFAIL);
+		return EX_TEMPFAIL;
 	}
 	if (pw == NULL) {
 		logwarn("unknown name: %s", name);
-		return(EX_NOUSER);
+		return EX_NOUSER;
 	}
 
 	(void)snprintf(path, sizeof path, "%s/%s", _PATH_MAILDIR, name);
@@ -222,21 +222,19 @@ deliver(int fd, char *name, int lockfile
 
 		if((lfd = open(lpath, O_CREAT|O_WRONLY|O_EXCL,
 		S_IRUSR|S_IWUSR)) < 0) {
-			logwarn("%s: %s", lpath, strerror(errno));
-			return(EX_OSERR);
+			logwarn("%s: can't create: %s", lpath, strerror(errno));
+			return EX_OSERR;
 		}
 	}
 
 	if (lstat(path, ) == -1) {
-	if (errno != ENOENT) {
-		logwarn("%s: %s", path, strerror(errno));
-		rval = EX_OSERR;
-		goto bad;
-	}
-	memset(, 0, sizeof(sb));
-	sb.st_dev = NODEV;
+		if (errno != ENOENT) {
+			logwarn("%s: can't stat: %s", path, strerror(errno));
+			goto bad;
+		}
+		memset(, 0, sizeof(sb));
+		sb.st_dev = NODEV;
 	} else if (badfile(path, )) {
-		rval = EX_OSERR;
 		goto bad;
 	}
 	
@@ -246,57 +244,55 @@ deliver(int fd, char *name, int lockfile
 		if (errno != ENOENT ||
 		   (mbfd = open(path, O_APPEND|O_CREAT|O_WRONLY|O_EXLOCK|O_EXCL,
 		 S_IRUSR|S_IWUSR)) == -1) {
-			logwarn("%s: %s", path, strerror(errno));
-			rval = EX_OSERR;
+			logwarn("%s: can't create: %s", path, strerror(errno));
 			goto bad;
 		}
 		created = 1;
 	} else {
 		/* opened existing file, check for TOCTTOU */
 		if (fstat(mbfd, ) == -1) {
-			rval = EX_OSERR;
+			logwarn("%s: can't stat: %s", path, strerror(errno));
 			goto bad;
 		}
 
 		if (badfile(path, )) {
-			rval = EX_OSERR;
 			goto bad;
 		}
 
 		/* file is not what we expected */
 		if (nsb.st_ino != sb.st_ino || nsb.st_dev != sb.st_dev) {
 			logwarn("%s: file has changed", path);
-			rval = EX_OSERR;
 			goto bad;
 		}
 	}
 
 	if ((curoff = lseek(mbfd, 0, SEEK_END)) == (off_t)-1) {
-		logwarn("%s: %s", path, strerror(errno));
-		rval = EX_OSERR;
+		logwarn("%s: can't seek: %s", path, strerror(errno));
 		goto bad;
 	}
 
 	(void)snprintf(biffmsg, sizeof biffmsg, "%s@%lld\n", name,
 	(long long)curoff);
 	if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
-		logwarn("temporary file: %s", strerror(errno));
-		rval = EX_OSERR;
+		logwarn("can't seek: %s", strerror(errno));
 		goto bad;
 	}
 
 	while ((nr = read(fd, buf, sizeof(buf))) > 0)
 		for (off = 0; off < nr;  off += nw)
 			if ((nw = write(mbfd, buf + off, nr - off)) < 0) {
-logwarn("%s: %s", path, strerror(errno));
+logwarn("%s: can't write: %s", path,
+strerror(errno));
 goto trunc;
 			}
+
 	if (nr < 0) {
-		logwarn("temporary file: %s", strerror(errno));
+		logwarn("can't read: %s", strerror(errno));
 trunc:		(void)ftruncate(mbfd, curoff);
-		rval = EX_OSERR;
+		goto bad;
 	}
 
+	rval = EX_OK;
 	/*
 	 * Set the owner and group.  Historically, binmail repeated this at
 	 * each mail delivery.  We no longer do this, assuming that if the



CVS commit: src/libexec/mail.local

2023-09-06 Thread Christos Zoulas
Module Name:src
Committed By:   christos
Date:   Wed Sep  6 20:16:05 UTC 2023

Modified Files:
src/libexec/mail.local: mail.local.c

Log Message:
KNF, clarify/provide warning messages, set rval to fail initially and only
set to success once everything works.


To generate a diff of this commit:
cvs rdiff -u -r1.30 -r1.31 src/libexec/mail.local/mail.local.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/libexec/mail.local

2023-09-06 Thread Mateusz Kocielski
Module Name:src
Committed By:   shm
Date:   Wed Sep  6 08:12:09 UTC 2023

Modified Files:
src/libexec/mail.local: mail.local.c

Log Message:
- remove lock file on error
- clarify diagnostic messages
- initialize struct stat if lstat(2) failed (from mhal at rbox dot co)
- ensure appending to a regular file


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/libexec/mail.local/mail.local.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/libexec/mail.local

2023-09-06 Thread Mateusz Kocielski
Module Name:src
Committed By:   shm
Date:   Wed Sep  6 08:12:09 UTC 2023

Modified Files:
src/libexec/mail.local: mail.local.c

Log Message:
- remove lock file on error
- clarify diagnostic messages
- initialize struct stat if lstat(2) failed (from mhal at rbox dot co)
- ensure appending to a regular file


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/libexec/mail.local/mail.local.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/libexec/mail.local/mail.local.c
diff -u src/libexec/mail.local/mail.local.c:1.29 src/libexec/mail.local/mail.local.c:1.30
--- src/libexec/mail.local/mail.local.c:1.29	Tue May 17 11:18:58 2022
+++ src/libexec/mail.local/mail.local.c	Wed Sep  6 08:12:09 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: mail.local.c,v 1.29 2022/05/17 11:18:58 kre Exp $	*/
+/*	$NetBSD: mail.local.c,v 1.30 2023/09/06 08:12:09 shm Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993, 1994
@@ -36,7 +36,7 @@ __COPYRIGHT("@(#) Copyright (c) 1990, 19
 #if 0
 static char sccsid[] = "@(#)mail.local.c	8.22 (Berkeley) 6/21/95";
 #else
-__RCSID("$NetBSD: mail.local.c,v 1.29 2022/05/17 11:18:58 kre Exp $");
+__RCSID("$NetBSD: mail.local.c,v 1.30 2023/09/06 08:12:09 shm Exp $");
 #endif
 #endif /* not lint */
 
@@ -51,6 +51,7 @@ __RCSID("$NetBSD: mail.local.c,v 1.29 20
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -137,7 +138,7 @@ store(const char *from)
 
 	tn = strdup(_PATH_LOCTMP);
 	if (!tn)
-		logerr(EX_OSERR, "not enough core");
+		logerr(EX_OSERR, "not enough memory");
 	if ((fd = mkstemp(tn)) == -1 || !(fp = fdopen(fd, "w+")))
 		logerr(EX_OSERR, "unable to open temporary file");
 	(void)unlink(tn);
@@ -175,13 +176,28 @@ store(const char *from)
 	return(fd);
 }
 
+static bool
+badfile(const char *path, const struct stat *sb)
+{
+	if (!S_ISREG(sb->st_mode)) {
+		logwarn("%s: not a regular file", path);
+		return true;
+	}
+
+	if (sb->st_nlink != 1) {
+		logwarn("%s: linked file", path);
+		return true;
+	}
+	return false;
+}
+
 static int
 deliver(int fd, char *name, int lockfile)
 {
 	struct stat sb, nsb;
 	struct passwd pwres, *pw;
 	char pwbuf[1024];
-	int created = 0, mbfd, nr, nw, off, rval=EX_OK, lfd = -1;
+	int created = 0, mbfd = -1, nr, nw, off, rval=EX_OK, lfd = -1;
 	char biffmsg[100], buf[8*1024], path[MAXPATHLEN], lpath[MAXPATHLEN];
 	off_t curoff;
 
@@ -211,10 +227,17 @@ deliver(int fd, char *name, int lockfile
 		}
 	}
 
-	if ((lstat(path, ) != -1) &&
-	(sb.st_nlink != 1 || S_ISLNK(sb.st_mode))) {
-		logwarn("%s: linked file", path);
-		return(EX_OSERR);
+	if (lstat(path, ) == -1) {
+	if (errno != ENOENT) {
+		logwarn("%s: %s", path, strerror(errno));
+		rval = EX_OSERR;
+		goto bad;
+	}
+	memset(, 0, sizeof(sb));
+	sb.st_dev = NODEV;
+	} else if (badfile(path, )) {
+		rval = EX_OSERR;
+		goto bad;
 	}
 	
 	if ((mbfd = open(path, O_APPEND|O_WRONLY|O_EXLOCK|O_NOFOLLOW,
@@ -235,8 +258,14 @@ deliver(int fd, char *name, int lockfile
 			goto bad;
 		}
 
+		if (badfile(path, )) {
+			rval = EX_OSERR;
+			goto bad;
+		}
+
 		/* file is not what we expected */
 		if (nsb.st_ino != sb.st_ino || nsb.st_dev != sb.st_dev) {
+			logwarn("%s: file has changed", path);
 			rval = EX_OSERR;
 			goto bad;
 		}



CVS commit: src/libexec/mail.local

2022-05-17 Thread Robert Elz
Module Name:src
Committed By:   kre
Date:   Tue May 17 11:18:58 UTC 2022

Modified Files:
src/libexec/mail.local: mail.local.c

Log Message:
fix local privilege escalation due to a race condition

NetBSD-SA2016-006 included an incomplete fix for CVE-2016-6253,
a local privilege escalation vulnerability in mail.local(8).

mail.local(8) attempts to open(2) a user's existing mailbox file
to append to it.  If that call fails, mail.local(8) will then issue
a second open(2) call to create the file (O_CREAT).

An attacker had the opportunity to create the file in question (as
a symlink, or link to some other file) in between these two open(2) calls.

Fix this by using O_EXCL in the 2nd open call, if the file exists when
that one happens, something is going wrong, so just abort.  Also, only
attempt that 2nd open if the reason the first failed was that the file
did not exist (this doesn't fix the issue, but it potentially saves
some cycles).

Thanks to Jan Schaumann for bringing this to our attention.


To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/libexec/mail.local/mail.local.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.



CVS commit: src/libexec/mail.local

2022-05-17 Thread Robert Elz
Module Name:src
Committed By:   kre
Date:   Tue May 17 11:18:58 UTC 2022

Modified Files:
src/libexec/mail.local: mail.local.c

Log Message:
fix local privilege escalation due to a race condition

NetBSD-SA2016-006 included an incomplete fix for CVE-2016-6253,
a local privilege escalation vulnerability in mail.local(8).

mail.local(8) attempts to open(2) a user's existing mailbox file
to append to it.  If that call fails, mail.local(8) will then issue
a second open(2) call to create the file (O_CREAT).

An attacker had the opportunity to create the file in question (as
a symlink, or link to some other file) in between these two open(2) calls.

Fix this by using O_EXCL in the 2nd open call, if the file exists when
that one happens, something is going wrong, so just abort.  Also, only
attempt that 2nd open if the reason the first failed was that the file
did not exist (this doesn't fix the issue, but it potentially saves
some cycles).

Thanks to Jan Schaumann for bringing this to our attention.


To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/libexec/mail.local/mail.local.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/libexec/mail.local/mail.local.c
diff -u src/libexec/mail.local/mail.local.c:1.28 src/libexec/mail.local/mail.local.c:1.29
--- src/libexec/mail.local/mail.local.c:1.28	Thu Jul 21 12:29:37 2016
+++ src/libexec/mail.local/mail.local.c	Tue May 17 11:18:58 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: mail.local.c,v 1.28 2016/07/21 12:29:37 shm Exp $	*/
+/*	$NetBSD: mail.local.c,v 1.29 2022/05/17 11:18:58 kre Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993, 1994
@@ -36,7 +36,7 @@ __COPYRIGHT("@(#) Copyright (c) 1990, 19
 #if 0
 static char sccsid[] = "@(#)mail.local.c	8.22 (Berkeley) 6/21/95";
 #else
-__RCSID("$NetBSD: mail.local.c,v 1.28 2016/07/21 12:29:37 shm Exp $");
+__RCSID("$NetBSD: mail.local.c,v 1.29 2022/05/17 11:18:58 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -217,11 +217,12 @@ deliver(int fd, char *name, int lockfile
 		return(EX_OSERR);
 	}
 	
-	if ((mbfd = open(path, O_APPEND|O_WRONLY|O_EXLOCK,
+	if ((mbfd = open(path, O_APPEND|O_WRONLY|O_EXLOCK|O_NOFOLLOW,
 	S_IRUSR|S_IWUSR)) == -1) {
 		/* create file */
-		if ((mbfd = open(path, O_APPEND|O_CREAT|O_WRONLY|O_EXLOCK,
-		S_IRUSR|S_IWUSR)) == -1) {
+		if (errno != ENOENT ||
+		   (mbfd = open(path, O_APPEND|O_CREAT|O_WRONLY|O_EXLOCK|O_EXCL,
+		 S_IRUSR|S_IWUSR)) == -1) {
 			logwarn("%s: %s", path, strerror(errno));
 			rval = EX_OSERR;
 			goto bad;