Check that the disk specified on the command line is the disk that
authorkrw <krw@openbsd.org>
Mon, 12 Oct 2015 20:52:20 +0000 (20:52 +0000)
committerkrw <krw@openbsd.org>
Mon, 12 Oct 2015 20:52:20 +0000 (20:52 +0000)
files are copied to. Error out with 'cross-device install' if not.

ok millert@, ok deraadt@ & jsing@ for previous version

usr.sbin/installboot/installboot.c
usr.sbin/installboot/installboot.h
usr.sbin/installboot/util.c

index f62f6b8..f414af5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: installboot.c,v 1.7 2015/10/08 14:50:38 krw Exp $     */
+/*     $OpenBSD: installboot.c,v 1.8 2015/10/12 20:52:20 krw Exp $     */
 
 /*
  * Copyright (c) 2012, 2013 Joel Sing <jsing@openbsd.org>
@@ -16,6 +16,9 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <sys/types.h>
+#include <sys/disklabel.h>
+#include <sys/stat.h>
 #include <err.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -29,6 +32,8 @@
 int    nowrite;
 int    stages;
 int    verbose;
+int    dstblkunit;
+int    dstblkmajor;
 
 char   *root = "/";
 char   *stage1;
@@ -48,7 +53,8 @@ usage(void)
 int
 main(int argc, char **argv)
 {
-       char *dev, *realdev;
+       struct stat sb;
+       char *dev, *realdev, *blkdev;
        int devfd, opt;
 
        md_init();
@@ -101,6 +107,15 @@ main(int argc, char **argv)
            &realdev)) < 0)
                err(1, "open: %s", realdev);
 
+       if (realdev == NULL || strncmp(realdev, "/dev/r", 6))
+               errx(1, "realdev");
+       if (asprintf(&blkdev, "/dev/%s", realdev+6) == -1)
+               err(1, "asprintf");
+       if (stat(blkdev, &sb) == -1)
+               err(1, "fstat");
+       dstblkunit = DISKUNIT(sb.st_rdev);
+       dstblkmajor = major(sb.st_rdev);
+
         if (verbose) {
                fprintf(stderr, "%s bootstrap on %s\n",
                    (nowrite ? "would install" : "installing"), realdev);
index af23ea5..5c9ad69 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: installboot.h,v 1.5 2015/10/08 14:50:38 krw Exp $     */
+/*     $OpenBSD: installboot.h,v 1.6 2015/10/12 20:52:20 krw Exp $     */
 /*
  * Copyright (c) 2012, 2013 Joel Sing <jsing@openbsd.org>
  *
@@ -18,6 +18,8 @@
 extern int nowrite;
 extern int stages;
 extern int verbose;
+extern int dstblkunit;
+extern int dstblkmajor;
 
 extern char *root;
 extern char *stage1;
index ce830ea..38206b8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: util.c,v 1.7 2015/10/08 14:50:38 krw Exp $    */
+/*     $OpenBSD: util.c,v 1.8 2015/10/12 20:52:20 krw Exp $    */
 
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -16,6 +16,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <sys/types.h>
+#include <sys/disklabel.h>
 #include <sys/stat.h>
 #include <err.h>
 #include <errno.h>
@@ -36,7 +38,7 @@ int
 filecopy(const char *srcfile, const char *dstfile)
 {
        struct stat sb;
-       ssize_t sz, n;
+       ssize_t srcsz, sz, n;
        int sfd, dfd, rslt = -1;
        char *buf;
 
@@ -54,13 +56,22 @@ filecopy(const char *srcfile, const char *dstfile)
                warn("fstat");
                return (-1);
        }
-       sz = sb.st_size;
+       srcsz = sz = sb.st_size;
 
        dfd = open(dstfile, O_WRONLY|O_CREAT);
        if (dfd == -1) {
                warn("open %s", dstfile);
                return (-1);
        }
+       if (fstat(dfd, &sb) == -1) {
+               warn("fstat");
+               return (-1);
+       }
+       if (major(sb.st_dev) != dstblkmajor || DISKUNIT(sb.st_dev) !=
+           dstblkunit) {
+               warnx("cross-device install");
+               return (-1);
+       }
        if (fchown(dfd, 0, 0) == -1)
                if (errno != EINVAL) {
                        warn("chown");
@@ -84,7 +95,7 @@ filecopy(const char *srcfile, const char *dstfile)
                }
        }
 
-       ftruncate(dfd, sb.st_size);
+       ftruncate(dfd, srcsz);
 
        close(dfd);
        close(sfd);