From 2e8b15db5da0980fffbe98c0a2a3626c3e921021 Mon Sep 17 00:00:00 2001 From: krw Date: Mon, 12 Oct 2015 20:52:20 +0000 Subject: [PATCH] Check that the disk specified on the command line is the disk that 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 | 19 +++++++++++++++++-- usr.sbin/installboot/installboot.h | 4 +++- usr.sbin/installboot/util.c | 19 +++++++++++++++---- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/usr.sbin/installboot/installboot.c b/usr.sbin/installboot/installboot.c index f62f6b8c54b..f414af56aba 100644 --- a/usr.sbin/installboot/installboot.c +++ b/usr.sbin/installboot/installboot.c @@ -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 @@ -16,6 +16,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include +#include #include #include #include @@ -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); diff --git a/usr.sbin/installboot/installboot.h b/usr.sbin/installboot/installboot.h index af23ea5f55c..5c9ad69c326 100644 --- a/usr.sbin/installboot/installboot.h +++ b/usr.sbin/installboot/installboot.h @@ -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 * @@ -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; diff --git a/usr.sbin/installboot/util.c b/usr.sbin/installboot/util.c index ce830ea79d0..38206b83133 100644 --- a/usr.sbin/installboot/util.c +++ b/usr.sbin/installboot/util.c @@ -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 @@ -16,6 +16,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include #include #include #include @@ -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); -- 2.20.1