Source-Changes-HG archive

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

[src/trunk]: src/usr.bin/calendar Repair accidental regression in -r1.49: for...



details:   https://anonhg.NetBSD.org/src/rev/e7ddc7be1ccb
branches:  trunk
changeset: 339168:e7ddc7be1ccb
user:      dholland <dholland%NetBSD.org@localhost>
date:      Wed Jul 01 06:48:25 2015 +0000

description:
Repair accidental regression in -r1.49: for -a mode, don't allow
calendars to be other than regular files unless the -x option is in
effect.

(If not in -a mode, we're running purely as the user whose calendar it
is and if they want to DoS themselves with named pipes it's their own
lookout.)

diffstat:

 usr.bin/calendar/calendar.c |  78 ++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 74 insertions(+), 4 deletions(-)

diffs (123 lines):

diff -r 32edeec7735f -r e7ddc7be1ccb usr.bin/calendar/calendar.c
--- a/usr.bin/calendar/calendar.c       Wed Jul 01 06:45:51 2015 +0000
+++ b/usr.bin/calendar/calendar.c       Wed Jul 01 06:48:25 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: calendar.c,v 1.51 2015/07/01 06:45:51 dholland Exp $   */
+/*     $NetBSD: calendar.c,v 1.52 2015/07/01 06:48:25 dholland Exp $   */
 
 /*
  * Copyright (c) 1989, 1993, 1994
@@ -39,10 +39,11 @@
 #if 0
 static char sccsid[] = "@(#)calendar.c 8.4 (Berkeley) 1/7/95";
 #endif
-__RCSID("$NetBSD: calendar.c,v 1.51 2015/07/01 06:45:51 dholland Exp $");
+__RCSID("$NetBSD: calendar.c,v 1.52 2015/07/01 06:48:25 dholland Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
+#include <sys/ioctl.h>
 #include <sys/time.h>
 #include <sys/stat.h>
 #include <sys/uio.h>
@@ -120,6 +121,7 @@
 static int      getmonth(char *);
 static bool     isnow(char *);
 static FILE    *opencal(FILE **);
+static int      tryopen(const char *, int);
 static void     settime(void);
 static void     usage(void) __dead;
 
@@ -403,7 +405,7 @@
        /* open up calendar file as stdin */
        if (fname == NULL) {
                for (const char **name = defaultnames; *name != NULL; name++) {
-                       if ((fd = open(*name, O_RDONLY)) == -1)
+                       if ((fd = tryopen(*name, O_RDONLY)) == -1)
                                continue;
                        else
                                break;
@@ -413,7 +415,7 @@
                                return NULL;
                        err(EXIT_FAILURE, "Cannot open calendar file");
                }
-       } else if ((fd = open(fname, O_RDONLY)) == -1) {
+       } else if ((fd = tryopen(fname, O_RDONLY)) == -1) {
                if (doall)
                        return NULL;
                err(EXIT_FAILURE, "Cannot open `%s'", fname);
@@ -482,6 +484,74 @@
        /*NOTREACHED*/
 }
 
+static int
+tryopen(const char *pathname, int flags)
+{
+       int fd, serrno, zero;
+       struct stat st;
+
+       /*
+        * XXX: cpp_restricted has inverted sense; it is false by default,
+        * and -x sets it to true. CPP_RESTRICTED is set in the environment
+        * if cpp_restricted is false... go figure. This should be fixed
+        * later.
+        */
+       if (doall && cpp_restricted == false) {
+               /*
+                * We are running with the user's euid, so they can't
+                * cause any mayhem (e.g. opening rewinding tape
+                * devices) that they couldn't do easily enough on
+                * their own. All we really need to worry about is opens
+                * that hang, because that would DoS the calendar run.
+                */
+               fd = open(pathname, flags | O_NONBLOCK);
+               if (fd == -1) {
+                       return -1;
+               }
+               if (fstat(fd, &st) == -1) {
+                       serrno = errno;
+                       close(fd);
+                       errno = serrno;
+                       return -1;
+               }
+               if (S_ISCHR(st.st_mode) ||
+                   S_ISBLK(st.st_mode) ||
+                   S_ISFIFO(st.st_mode)) {
+                       close(fd);
+
+                       /* Call shenanigans in the daily output */
+                       errno = EPERM;
+                       warn("%s: %s", pw->pw_name, pathname);
+
+                       errno = EPERM;
+                       return -1;
+               }
+               if (S_ISDIR(st.st_mode)) {
+                       /* Don't warn about this */
+                       close(fd);
+                       errno = EISDIR;
+                       return -1;
+               }
+               if (!S_ISREG(st.st_mode)) {
+                       /* There shouldn't be other cases to go here */
+                       close(fd);
+                       errno = EINVAL;
+                       return -1;
+               }
+               zero = 0;
+               if (ioctl(fd, FIONBIO, &zero) == -1) {
+                       serrno = errno;
+                       warn("%s: %s: FIONBIO", pw->pw_name, pathname);
+                       close(fd);
+                       errno = serrno;
+                       return -1;
+               }
+               return fd;
+       } else {
+               return open(pathname, flags);
+       }
+}
+
 static void
 closecal(FILE *fp)
 {



Home | Main Index | Thread Index | Old Index