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:
/*