From c0c611b7d51f68b61b6e3eea76f604bbb21048f3 Mon Sep 17 00:00:00 2001 From: deraadt Date: Wed, 14 Oct 2015 16:58:55 +0000 Subject: [PATCH] Since the fsck_* programs now only handle one filesystem, this creates a point where open() and disklabel reading have completed. After that point, pledge "stdio". As a result, an fsck of a hostile partition (noone ever does that, or do they? :) is done by a program with SUBSTANTIALLY less system call exposure. ok semarie --- sbin/fsck_ext2fs/setup.c | 49 +++++++++++++++++++++++----------------- sbin/fsck_ffs/setup.c | 22 +++++++++++------- sbin/fsck_msdos/check.c | 6 ++++- 3 files changed, 47 insertions(+), 30 deletions(-) diff --git a/sbin/fsck_ext2fs/setup.c b/sbin/fsck_ext2fs/setup.c index f2748b26f5d..b709fc0da55 100644 --- a/sbin/fsck_ext2fs/setup.c +++ b/sbin/fsck_ext2fs/setup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: setup.c,v 1.27 2015/09/10 15:21:40 deraadt Exp $ */ +/* $OpenBSD: setup.c,v 1.28 2015/10/14 16:58:55 deraadt Exp $ */ /* $NetBSD: setup.c,v 1.1 1997/06/11 11:22:01 bouyer Exp $ */ /* @@ -10,13 +10,13 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -45,8 +45,10 @@ #include #include #include +#include #include #include +#include #include "fsck.h" #include "extern.h" @@ -55,7 +57,7 @@ #define POWEROF2(num) (((num) & ((num) - 1)) == 0) void badsb(int, char *); -int calcsb(char *, int, struct m_ext2fs *); +int calcsb(char *, int, struct m_ext2fs *, struct disklabel *); static struct disklabel *getdisklabel(char *, int); static int readsb(int); @@ -105,15 +107,21 @@ setup(char *dev) asblk.b_un.b_buf = malloc(SBSIZE); if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL) errexit("cannot allocate space for superblock\n"); - if ((lp = getdisklabel((char *)NULL, fsreadfd)) != NULL) + if ((lp = getdisklabel(NULL, fsreadfd)) != NULL) secsize = lp->d_secsize; else secsize = DEV_BSIZE; + + if (!hotroot()) { + if (pledge("stdio", NULL) == -1) + err(1, "pledge"); + } + /* * Read in the superblock, looking for alternates if necessary */ if (readsb(1) == 0) { - if (bflag || preen || calcsb(dev, fsreadfd, &proto) == 0) + if (bflag || preen || calcsb(dev, fsreadfd, &proto, lp) == 0) return(0); if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0) return (0); @@ -125,12 +133,12 @@ setup(char *dev) } if (cg >= proto.e2fs_ncg) { printf("%s %s\n%s %s\n%s %s\n", - "SEARCH FOR ALTERNATE SUPER-BLOCK", - "FAILED. YOU MUST USE THE", - "-b OPTION TO FSCK_FFS TO SPECIFY THE", - "LOCATION OF AN ALTERNATE", - "SUPER-BLOCK TO SUPPLY NEEDED", - "INFORMATION; SEE fsck_ext2fs(8)."); + "SEARCH FOR ALTERNATE SUPER-BLOCK", + "FAILED. YOU MUST USE THE", + "-b OPTION TO FSCK_FFS TO SPECIFY THE", + "LOCATION OF AN ALTERNATE", + "SUPER-BLOCK TO SUPPLY NEEDED", + "INFORMATION; SEE fsck_ext2fs(8)."); return(0); } doskipclean = 0; @@ -141,7 +149,7 @@ setup(char *dev) if (sblock.e2fs.e2fs_state == E2FS_ISCLEAN) { if (doskipclean) { pwarn("%sile system is clean; not checking\n", - preen ? "f" : "** F"); + preen ? "f" : "** F"); return (-1); } if (!preen) @@ -421,11 +429,9 @@ badsb(int listerr, char *s) * can be used. Do NOT attempt to use other macros without verifying that * their needed information is available! */ - int -calcsb(char *dev, int devfd, struct m_ext2fs *fs) +calcsb(char *dev, int devfd, struct m_ext2fs *fs, struct disklabel *lp) { - struct disklabel *lp; struct partition *pp; char *cp; @@ -436,7 +442,8 @@ calcsb(char *dev, int devfd, struct m_ext2fs *fs) return (0); } cp--; - lp = getdisklabel(dev, devfd); + if (lp == NULL) + pfatal("%s: CANNOT READ DISKLABEL\n", dev); if (isdigit((unsigned char)*cp)) pp = &lp->d_partitions[0]; else @@ -477,7 +484,7 @@ getdisklabel(char *s, int fd) if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { if (s == NULL) - return ((struct disklabel *)NULL); + return (NULL); pwarn("ioctl (GCINFO): %s\n", strerror(errno)); errexit("%s: can't read disk label\n", s); } diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c index 45b8ff5c91a..9c0e40c0daa 100644 --- a/sbin/fsck_ffs/setup.c +++ b/sbin/fsck_ffs/setup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: setup.c,v 1.57 2015/01/20 18:22:21 deraadt Exp $ */ +/* $OpenBSD: setup.c,v 1.58 2015/10/14 16:58:55 deraadt Exp $ */ /* $NetBSD: setup.c,v 1.27 1996/09/27 22:45:19 christos Exp $ */ /* @@ -44,11 +44,12 @@ #include #include #include +#include #include #include -#include #include #include +#include #include "fsck.h" #include "extern.h" @@ -60,7 +61,7 @@ #define POWEROF2(num) (((num) & ((num) - 1)) == 0) void badsb(int, char *); -int calcsb(char *, int, struct fs *); +int calcsb(char *, int, struct fs *, struct disklabel *); static struct disklabel *getdisklabel(char *, int); static int readsb(int); static int cmpsb(struct fs *, struct fs *); @@ -138,11 +139,17 @@ setup(char *dev) secsize = lp->d_secsize; else secsize = DEV_BSIZE; + + if (!hotroot()) { + if (pledge("stdio", NULL) == -1) + err(1, "pledge"); + } + /* * Read in the superblock, looking for alternates if necessary */ if (readsb(1) == 0) { - if (bflag || preen || calcsb(realdev, fsreadfd, &proto) == 0) + if (bflag || preen || calcsb(realdev, fsreadfd, &proto, lp) == 0) return(0); if (reply("LOOK FOR ALTERNATE SUPERBLOCKS") == 0) return (0); @@ -425,7 +432,6 @@ badsblabel: return (0); } - /* * Read in the super block and its summary info. */ @@ -575,9 +581,8 @@ badsb(int listerr, char *s) * their needed information is available! */ int -calcsb(char *dev, int devfd, struct fs *fs) +calcsb(char *dev, int devfd, struct fs *fs, struct disklabel *lp) { - struct disklabel *lp; struct partition *pp; char *cp; int i; @@ -589,7 +594,8 @@ calcsb(char *dev, int devfd, struct fs *fs) return (0); } cp--; - lp = getdisklabel(dev, devfd); + if (lp == NULL) + pfatal("%s: CANNOT READ DISKLABEL\n", dev); if (isdigit((unsigned char)*cp)) pp = &lp->d_partitions[0]; else diff --git a/sbin/fsck_msdos/check.c b/sbin/fsck_msdos/check.c index 952e0901f1a..bfe9450f2b1 100644 --- a/sbin/fsck_msdos/check.c +++ b/sbin/fsck_msdos/check.c @@ -1,4 +1,4 @@ -/* $OpenBSD: check.c,v 1.17 2015/01/16 06:39:58 deraadt Exp $ */ +/* $OpenBSD: check.c,v 1.18 2015/10/14 16:58:55 deraadt Exp $ */ /* $NetBSD: check.c,v 1.8 1997/10/17 11:19:29 ws Exp $ */ /* @@ -38,6 +38,7 @@ #include #include #include +#include #include "ext.h" @@ -77,6 +78,9 @@ checkfilesys(const char *fname) if (ioctl(dosfs, DIOCGDINFO, (char *)&lab) < 0) pfatal("can't read disk label for %s\n", fname); + if (pledge("stdio", NULL) == -1) + err(1, "pledge"); + if (readboot(dosfs, &boot) != FSOK) { (void)close(dosfs); return (8); -- 2.20.1