Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-6-1]: src Pull up following revision(s) (requested by spz in tick...
details: https://anonhg.NetBSD.org/src/rev/b12e3d068481
branches: netbsd-6-1
changeset: 776275:b12e3d068481
user: snj <snj%NetBSD.org@localhost>
date: Sun Nov 05 20:04:00 2017 +0000
description:
Pull up following revision(s) (requested by spz in ticket #1509):
external/bsd/nvi/usr.bin/recover/virecover: 1.2-1.3 via patch
external/bsd/nvi/dist/common/recover.c: revision 1.6-1.9 via patch
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.
Put back the tests for "no files matched" (in a different way than they
were written previously - but that's just style.) This is not csh...
Use the correct test operator to test for an empty file (rather than
testing for an empty file name...)
Write test ('[') commands in a way that is defined to work, rather than
just happens to - we can afford the (negligible) performance hit here.
- don't use command substitution to glob a pattern into a list of filenames;
it is less efficient than doing it directly and does not handle whitespace
in filenames properly.
- change test to [
- quote variables
Deal safely with recovery mail files.
oops, accidendally committed an earlier non-working version; fixed.
Don't use popenve() for portability; forking an extra shell here is not an
issue.
diffstat:
dist/nvi/common/recover.c | 89 ++++++++++++++++++++++++++++++++++--------
usr.bin/nvi/recover/virecover | 70 +++++++++++++++++---------------
2 files changed, 108 insertions(+), 51 deletions(-)
diffs (227 lines):
diff -r 8efc8329203f -r b12e3d068481 dist/nvi/common/recover.c
--- a/dist/nvi/common/recover.c Sun Nov 05 19:55:16 2017 +0000
+++ b/dist/nvi/common/recover.c Sun Nov 05 20:04:00 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: recover.c,v 1.3 2009/01/18 03:45:50 lukem Exp $ */
+/* $NetBSD: recover.c,v 1.3.24.1 2017/11/05 20:04:00 snj Exp $ */
/*-
* Copyright (c) 1993, 1994
@@ -112,7 +112,7 @@
#define VI_PHEADER "X-vi-recover-path: "
static int rcv_copy __P((SCR *, int, char *));
-static void rcv_email __P((SCR *, char *));
+static void rcv_email __P((SCR *, const char *));
static char *rcv_gets __P((char *, size_t, int));
static int rcv_mailfile __P((SCR *, int, char *));
static int rcv_mktemp __P((SCR *, char *, const char *, int));
@@ -470,6 +470,23 @@
}
/*
+ * 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
@@ -513,9 +530,14 @@
* 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:
/*
@@ -626,9 +648,16 @@
* 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:
/*
@@ -836,24 +865,48 @@
* Send email.
*/
static void
-rcv_email(SCR *sp, char *fname)
+rcv_email(SCR *sp, const char *fname)
{
struct stat sb;
- char buf[MAXPATHLEN * 2 + 20];
+ char buf[BUFSIZ];
+ FILE *fin, *fout;
+ size_t l;
- if (_PATH_SENDMAIL[0] != '/' || stat(_PATH_SENDMAIL, &sb))
+ if (_PATH_SENDMAIL[0] != '/' || stat(_PATH_SENDMAIL, &sb) == -1) {
msgq_str(sp, M_SYSERR,
_PATH_SENDMAIL, "071|not sending email: %s");
- else {
- /*
- * !!!
- * If you need to port this to a system that doesn't have
- * sendmail, the -t flag causes sendmail to read the message
- * for the recipients instead of specifying them some other
- * way.
- */
- (void)snprintf(buf, sizeof(buf),
- "%s -t < %s", _PATH_SENDMAIL, fname);
- (void)system(buf);
+ return;
+ }
+
+ /*
+ * !!!
+ * If you need to port this to a system that doesn't have
+ * sendmail, the -t flag causes sendmail to read the message
+ * for the recipients instead of specifying them some other
+ * way.
+ */
+ if ((fin = fopen(fname, "refl")) == NULL) {
+ msgq_str(sp, M_SYSERR,
+ fname, "325|cannot open: %s");
+ return;
}
+
+ if (!checkok(fileno(fin))) {
+ (void)fclose(fin);
+ return;
+ }
+
+ fout = popen(_PATH_SENDMAIL " -t", "w");
+ if (fout == NULL) {
+ msgq_str(sp, M_SYSERR,
+ _PATH_SENDMAIL, "326|cannot execute sendmail: %s");
+ fclose(fin);
+ return;
+ }
+
+ while ((l = fread(buf, 1, sizeof(buf), fin)) != 0)
+ (void)fwrite(buf, 1, l, fout);
+
+ (void)fclose(fin);
+ (void)pclose(fout);
}
diff -r 8efc8329203f -r b12e3d068481 usr.bin/nvi/recover/virecover
--- a/usr.bin/nvi/recover/virecover Sun Nov 05 19:55:16 2017 +0000
+++ b/usr.bin/nvi/recover/virecover Sun Nov 05 20:04:00 2017 +0000
@@ -1,6 +1,6 @@
#!/bin/sh -
#
-# $NetBSD: virecover,v 1.1 2008/09/02 09:25:39 christos Exp $
+# $NetBSD: virecover,v 1.1.36.1 2017/11/05 20:04:00 snj Exp $
#
# @(#)recover.in 8.8 (Berkeley) 10/10/96
#
@@ -10,40 +10,44 @@
SENDMAIL="/usr/sbin/sendmail"
# Check editor backup files.
-vibackup=`echo $RECDIR/vi.*`
-if [ "$vibackup" != "$RECDIR/vi.*" ]; then
- for i in $vibackup; do
- # Only test files that are readable.
- if test ! -f $i || test ! -r $i; then
- continue
- fi
+for i in $RECDIR/vi.*; do
+
+ case "$i" in
+ $RECDIR/vi.\*) continue;;
+ esac
- # Unmodified nvi editor backup files either have the
- # execute bit set or are zero length. Delete them.
- if test -x $i -o ! -s $i; then
- rm $i
- fi
- done
-fi
+ # Only test files that are readable.
+ if ! [ -f "$i" ] || ! [ -r "$i" ]; then
+ continue
+ fi
+
+ # Unmodified nvi editor backup files either have the
+ # execute bit set or are zero length. Delete them.
+ if [ -x "$i" ] || ! [ -s "$i" ]; then
+ rm -f "$i"
+ fi
+done
# It is possible to get incomplete recovery files, if the editor crashes
# at the right time.
-virecovery=`echo $RECDIR/recover.*`
-if [ "$virecovery" != "$RECDIR/recover.*" ]; then
- for i in $virecovery; do
- # Only test files that are readable.
- if test ! -r $i; then
- continue
- fi
+for i in $RECDIR/recover.*; do
+
+ case "$i" in
+ $RECDIR/recover.\*) continue;;
+ esac
+
+ # Only test files that are readable.
+ if ! [ -r "$i" ]; then
+ continue
+ fi
- # Delete any recovery files that are zero length, corrupted,
- # or that have no corresponding backup file. Else send mail
- # to the user.
- recfile=`awk '/^X-vi-recover-path:/{print $2}' < $i`
- if test -n "$recfile" -a -s "$recfile"; then
- $SENDMAIL -t < $i
- else
- rm $i
- fi
- done
-fi
+ # Delete any recovery files that are zero length, corrupted,
+ # or that have no corresponding backup file. Else send mail
+ # to the user.
+ recfile=$(awk '/^X-vi-recover-path:/{print $2}' < "$i")
+ if [ -n "$recfile" ] && [ -s "$recfile" ]; then
+ $SENDMAIL -t < "$i"
+ else
+ rm -f "$i"
+ fi
+done
Home |
Main Index |
Thread Index |
Old Index