Source-Changes-HG archive

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

[src/trunk]: src/external/bsd/nvi/dist/common make the checkok test stricter ...



details:   https://anonhg.NetBSD.org/src/rev/279f550c664f
branches:  trunk
changeset: 827733:279f550c664f
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Nov 10 16:35:54 2017 +0000

description:
make the checkok test stricter to avoid races, and use O_REGULAR.

diffstat:

 external/bsd/nvi/dist/common/recover.c |  17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

diffs (59 lines):

diff -r 022b4d21fb98 -r 279f550c664f external/bsd/nvi/dist/common/recover.c
--- a/external/bsd/nvi/dist/common/recover.c    Fri Nov 10 14:53:00 2017 +0000
+++ b/external/bsd/nvi/dist/common/recover.c    Fri Nov 10 16:35:54 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: recover.c,v 1.9 2017/11/04 14:20:12 christos Exp $ */
+/*     $NetBSD: recover.c,v 1.10 2017/11/10 16:35:54 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.9 2017/11/04 14:20:12 christos Exp $");
+__RCSID("$NetBSD: recover.c,v 1.10 2017/11/10 16:35:54 christos Exp $");
 #endif
 
 #include <sys/param.h>
@@ -121,6 +121,10 @@
 static int      rcv_mailfile(SCR *, int, char *);
 static int      rcv_mktemp(SCR *, char *, const char *, int);
 
+#ifndef O_REGULAR
+#define O_REGULAR O_NONBLOCK
+#endif
+
 /*
  * rcv_tmp --
  *     Build a file name that will be used as the recovery file.
@@ -487,14 +491,19 @@
  * 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.
+ *
+ * Checking the mode is racy though (someone can chmod between the
+ * open and the stat call, so also check for uid match or root.
  */
 static int
 checkok(int fd)
 {
        struct stat sb;
+       uid_t uid = getuid();
 
        return fstat(fd, &sb) != -1 && S_ISREG(sb.st_mode) &&
-           (sb.st_mode & (S_IRWXG|S_IRWXO)) == 0;
+           (sb.st_mode & (S_IRWXG|S_IRWXO)) == 0 &&
+           (uid == 0 || uid == sb.st_uid);
 }
 
 /*
@@ -659,7 +668,7 @@
                 * 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|O_NONBLOCK|O_NOFOLLOW|O_CLOEXEC,
+               if ((fd = open(recpath, O_RDWR|O_REGULAR|O_NOFOLLOW|O_CLOEXEC,
                    0)) == -1)
                        continue;
 



Home | Main Index | Thread Index | Old Index