Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-8]: src Pull up following revision(s) (requested by christos in t...
details: https://anonhg.NetBSD.org/src/rev/e6eb914f1738
branches: netbsd-8
changeset: 434888:e6eb914f1738
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Thu Apr 12 01:45:57 2018 +0000
description:
Pull up following revision(s) (requested by christos in ticket #741):
lib/libc/stdio/flags.c: revision 1.19
lib/libc/stdio/fdopen.c: revision 1.18
sys/kern/vfs_vnops.c: revision 1.196
lib/libc/stdio/freopen.c: revision 1.20
lib/libc/stdio/fopen.c: revision 1.17
external/bsd/nvi/dist/common/recover.c: revision 1.10
external/bsd/nvi/dist/common/recover.c: revision 1.11
lib/libc/sys/open.2: revision 1.58
sys/sys/fcntl.h: revision 1.49
make the checkok test stricter to avoid races, and use O_REGULAR.
Instead of opening the file and using popen(3), pass the file descriptor
to sendmail directory. Idea and code from Todd Miller.
Add O_REGULAR to enforce opening of only regular files
(like we have O_DIRECTORY for directories).
This is better than open(, O_NONBLOCK), fstat()+S_ISREG() because opening
devices can have side effects.
diffstat:
external/bsd/nvi/dist/common/recover.c | 72 ++++++++++++++++++---------------
lib/libc/stdio/fdopen.c | 6 +-
lib/libc/stdio/flags.c | 6 +-
lib/libc/stdio/fopen.c | 18 +-------
lib/libc/stdio/freopen.c | 19 +--------
lib/libc/sys/open.2 | 6 +-
sys/kern/vfs_vnops.c | 7 ++-
sys/sys/fcntl.h | 5 +-
8 files changed, 61 insertions(+), 78 deletions(-)
diffs (truncated from 367 to 300 lines):
diff -r 7663a8f55e10 -r e6eb914f1738 external/bsd/nvi/dist/common/recover.c
--- a/external/bsd/nvi/dist/common/recover.c Thu Apr 12 01:38:42 2018 +0000
+++ b/external/bsd/nvi/dist/common/recover.c Thu Apr 12 01:45:57 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: recover.c,v 1.5.22.1 2017/11/06 09:37:24 snj Exp $ */
+/* $NetBSD: recover.c,v 1.5.22.2 2018/04/12 01:45:57 msaitoh Exp $ */
/*-
* Copyright (c) 1993, 1994
* The Regents of the University of California. All rights reserved.
@@ -16,12 +16,13 @@
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.22.1 2017/11/06 09:37:24 snj Exp $");
+__RCSID("$NetBSD: recover.c,v 1.5.22.2 2018/04/12 01:45:57 msaitoh Exp $");
#endif
#include <sys/param.h>
#include <sys/types.h> /* XXX: param.h may not have included types.h */
#include <sys/queue.h>
+#include <sys/wait.h>
#include <sys/stat.h>
/*
@@ -116,11 +117,15 @@
#define VI_PHEADER "X-vi-recover-path: "
static int rcv_copy(SCR *, int, char *);
-static void rcv_email(SCR *, const char *);
+static void rcv_email(SCR *, int fd);
static char *rcv_gets(char *, size_t, int);
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.
@@ -286,7 +291,7 @@
/* REQUEST: send email. */
if (LF_ISSET(RCV_EMAIL))
- rcv_email(sp, ep->rcv_mpath);
+ rcv_email(sp, ep->rcv_fd);
}
/*
@@ -466,7 +471,7 @@
}
if (issync) {
- rcv_email(sp, mpath);
+ rcv_email(sp, fd);
if (close(fd)) {
werr: msgq(sp, M_SYSERR, "065|Recovery file");
goto err;
@@ -487,14 +492,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 +669,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;
@@ -876,12 +886,10 @@
* Send email.
*/
static void
-rcv_email(SCR *sp, const char *fname)
+rcv_email(SCR *sp, int fd)
{
struct stat sb;
- char buf[BUFSIZ];
- FILE *fin, *fout;
- size_t l;
+ pid_t pid;
if (_PATH_SENDMAIL[0] != '/' || stat(_PATH_SENDMAIL, &sb) == -1) {
msgq_str(sp, M_SYSERR,
@@ -896,28 +904,26 @@
* 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;
+ switch (pid = fork()) {
+ case -1: /* Error. */
+ msgq(sp, M_SYSERR, "fork");
+ break;
+ case 0: /* Sendmail. */
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ msgq(sp, M_SYSERR, "lseek");
+ _exit(127);
+ }
+ if (fd != STDIN_FILENO) {
+ (void)dup2(fd, STDIN_FILENO);
+ (void)close(fd);
+ }
+ execl(_PATH_SENDMAIL, "sendmail", "-t", NULL);
+ msgq(sp, M_SYSERR, _PATH_SENDMAIL);
+ _exit(127);
+ default: /* Parent. */
+ while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
+ continue;
+ break;
}
- 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 7663a8f55e10 -r e6eb914f1738 lib/libc/stdio/fdopen.c
--- a/lib/libc/stdio/fdopen.c Thu Apr 12 01:38:42 2018 +0000
+++ b/lib/libc/stdio/fdopen.c Thu Apr 12 01:45:57 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fdopen.c,v 1.17 2017/01/10 17:00:58 christos Exp $ */
+/* $NetBSD: fdopen.c,v 1.17.6.1 2018/04/12 01:45:57 msaitoh Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)fdopen.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: fdopen.c,v 1.17 2017/01/10 17:00:58 christos Exp $");
+__RCSID("$NetBSD: fdopen.c,v 1.17.6.1 2018/04/12 01:45:57 msaitoh Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -92,7 +92,7 @@
return NULL;
}
- if (oflags & O_NONBLOCK) {
+ if (oflags & O_REGULAR) {
struct stat st;
if (fstat(fd, &st) == -1) {
return NULL;
diff -r 7663a8f55e10 -r e6eb914f1738 lib/libc/stdio/flags.c
--- a/lib/libc/stdio/flags.c Thu Apr 12 01:38:42 2018 +0000
+++ b/lib/libc/stdio/flags.c Thu Apr 12 01:45:57 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: flags.c,v 1.17 2012/11/15 03:50:36 christos Exp $ */
+/* $NetBSD: flags.c,v 1.17.22.1 2018/04/12 01:45:57 msaitoh Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)flags.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: flags.c,v 1.17 2012/11/15 03:50:36 christos Exp $");
+__RCSID("$NetBSD: flags.c,v 1.17.22.1 2018/04/12 01:45:57 msaitoh Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -99,7 +99,7 @@
m = O_RDWR;
break;
case 'f':
- o |= O_NONBLOCK;
+ o |= O_REGULAR;
break;
case 'e':
o |= O_CLOEXEC;
diff -r 7663a8f55e10 -r e6eb914f1738 lib/libc/stdio/fopen.c
--- a/lib/libc/stdio/fopen.c Thu Apr 12 01:38:42 2018 +0000
+++ b/lib/libc/stdio/fopen.c Thu Apr 12 01:45:57 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fopen.c,v 1.15 2012/03/15 18:22:30 christos Exp $ */
+/* $NetBSD: fopen.c,v 1.15.24.1 2018/04/12 01:45:57 msaitoh Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)fopen.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: fopen.c,v 1.15 2012/03/15 18:22:30 christos Exp $");
+__RCSID("$NetBSD: fopen.c,v 1.15.24.1 2018/04/12 01:45:57 msaitoh Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -66,20 +66,6 @@
return NULL;
if ((f = open(file, oflags, DEFFILEMODE)) < 0)
goto release;
- if (oflags & O_NONBLOCK) {
- struct stat st;
- if (fstat(f, &st) == -1) {
- int sverrno = errno;
- (void)close(f);
- errno = sverrno;
- goto release;
- }
- if (!S_ISREG(st.st_mode)) {
- (void)close(f);
- errno = EFTYPE;
- goto release;
- }
- }
/*
* File descriptors are a full int, but _file is only a short.
* If we get a valid file descriptor that is greater or equal to
diff -r 7663a8f55e10 -r e6eb914f1738 lib/libc/stdio/freopen.c
--- a/lib/libc/stdio/freopen.c Thu Apr 12 01:38:42 2018 +0000
+++ b/lib/libc/stdio/freopen.c Thu Apr 12 01:45:57 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: freopen.c,v 1.19 2012/03/27 15:05:42 christos Exp $ */
+/* $NetBSD: freopen.c,v 1.19.24.1 2018/04/12 01:45:57 msaitoh Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)freopen.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: freopen.c,v 1.19 2012/03/27 15:05:42 christos Exp $");
+__RCSID("$NetBSD: freopen.c,v 1.19.24.1 2018/04/12 01:45:57 msaitoh Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -141,21 +141,6 @@
return NULL;
}
- if (oflags & O_NONBLOCK) {
- struct stat st;
- if (fstat(f, &st) == -1) {
- sverrno = errno;
- (void)close(f);
- errno = sverrno;
- return NULL;
- }
- if (!S_ISREG(st.st_mode)) {
- (void)close(f);
- errno = EFTYPE;
- return NULL;
- }
- }
-
/*
* If reopening something that was open before on a real file, try
* to maintain the descriptor. Various C library routines (perror)
diff -r 7663a8f55e10 -r e6eb914f1738 lib/libc/sys/open.2
--- a/lib/libc/sys/open.2 Thu Apr 12 01:38:42 2018 +0000
+++ b/lib/libc/sys/open.2 Thu Apr 12 01:45:57 2018 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: open.2,v 1.57 2017/05/14 12:30:37 wiz Exp $
+.\" $NetBSD: open.2,v 1.57.2.1 2018/04/12 01:45:57 msaitoh Exp $
.\"
.\" Copyright (c) 1980, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" @(#)open.2 8.2 (Berkeley) 11/16/93
.\"
-.Dd July 29, 2013
Home |
Main Index |
Thread Index |
Old Index