Module Name:    src
Committed By:   christos
Date:           Sat Nov  4 03:26:41 UTC 2017

Modified Files:
        src/external/bsd/nvi/dist/common: recover.c

Log Message:
be more careful about opening recovery files... in particular deal with
people trying to get 'vi -r' stuck using named pipes, symlink attacks,
and coercing others opening recovery files they did not create.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/external/bsd/nvi/dist/common/recover.c

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

Modified files:

Index: src/external/bsd/nvi/dist/common/recover.c
diff -u src/external/bsd/nvi/dist/common/recover.c:1.5 src/external/bsd/nvi/dist/common/recover.c:1.6
--- src/external/bsd/nvi/dist/common/recover.c:1.5	Sun Jan 26 16:43:45 2014
+++ src/external/bsd/nvi/dist/common/recover.c	Fri Nov  3 23:26:41 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: recover.c,v 1.5 2014/01/26 21:43:45 christos Exp $ */
+/*	$NetBSD: recover.c,v 1.6 2017/11/04 03:26:41 christos Exp $ */
 /*-
  * Copyright (c) 1993, 1994
  *	The Regents of the University of California.  All rights reserved.
@@ -16,7 +16,7 @@
 static const char sccsid[] = "Id: recover.c,v 10.31 2001/11/01 15:24:44 skimo Exp  (Berkeley) Date: 2001/11/01 15:24:44 ";
 #endif /* not lint */
 #else
-__RCSID("$NetBSD: recover.c,v 1.5 2014/01/26 21:43:45 christos Exp $");
+__RCSID("$NetBSD: recover.c,v 1.6 2017/11/04 03:26:41 christos Exp $");
 #endif
 
 #include <sys/param.h>
@@ -482,6 +482,22 @@ err:	if (!issync)
 }
 
 /*
+ * Since vi creates recovery files only accessible by the user, files
+ * accessible by group or others are probably malicious so avoid them.
+ * This is simpler than checking for getuid() == st.st_uid and we want
+ * to preserve the functionality that root can recover anything which
+ * means that root should know better and be careful.
+ */
+static int
+checkok(int fd)
+{
+	struct stat sb;
+
+	return fstat(fd, &sb) != -1 && S_ISREG(sb.st_mode) &&
+	    (sb.st_mode & (S_IRWXG|S_IRWXO)) == 0;
+}
+
+/*
  *	people making love
  *	never exactly the same
  *	just like a snowflake
@@ -525,9 +541,14 @@ rcv_list(SCR *sp)
 		 * if we're using fcntl(2), there's no way to lock a file
 		 * descriptor that's not open for writing.
 		 */
-		if ((fp = fopen(dp->d_name, "r+")) == NULL)
+		if ((fp = fopen(dp->d_name, "r+efl")) == NULL)
 			continue;
 
+		if (!checkok(fileno(fp))) {
+			(void)fclose(fp);
+			continue;
+		}
+
 		switch (file_lock(sp, NULL, NULL, fileno(fp), 1)) {
 		case LOCK_FAILED:
 			/*
@@ -638,9 +659,15 @@ rcv_read(SCR *sp, FREF *frp)
 		 * if we're using fcntl(2), there's no way to lock a file
 		 * descriptor that's not open for writing.
 		 */
-		if ((fd = open(recpath, O_RDWR, 0)) == -1)
+		if ((fd = open(recpath, O_RDWR|O_NONBLOCK|O_NOFOLLOW|O_CLOEXEC,
+		    0)) == -1)
 			continue;
 
+		if (!checkok(fd)) {
+			(void)close(fd);
+			continue;
+		}
+
 		switch (file_lock(sp, NULL, NULL, fd, 1)) {
 		case LOCK_FAILED:
 			/*

Reply via email to