Add check(s) in vmd/vmctl to ensure a VM's disk are regular files.

Tested with the following:
vmctl start "test1" -d /dev/sd3c #block device
vmctl start "test2" -d /dev/rsd3c #char device
vmctl start "test3" -d fifo #named pipe

Comments? Ok?

diff --git usr.sbin/vmctl/vmctl.c usr.sbin/vmctl/vmctl.c
index f694f61e48c..e3db6a78c5b 100644
--- usr.sbin/vmctl/vmctl.c
+++ usr.sbin/vmctl/vmctl.c
@@ -204,6 +204,11 @@ vm_start_complete(struct imsg *imsg, int *ret, int 
autoconnect)
                                warnx("could not find specified disk image(s)");
                                *ret = ENOENT;
                                break;
+                       case VMD_DISK_INVALID:
+                               warnx("specified disk image(s) are "
+                                        "not regular files");
+                               *ret = ENOENT;
+                               break;
                        default:
                                errno = res;
                                warn("start vm command failed");
diff --git usr.sbin/vmd/config.c usr.sbin/vmd/config.c
index 1e1166f8263..ced7ab666b4 100644
--- usr.sbin/vmd/config.c
+++ usr.sbin/vmd/config.c
@@ -20,6 +20,7 @@
 #include <sys/queue.h>
 #include <sys/time.h>
 #include <sys/uio.h>
+#include <sys/stat.h>
 #include <sys/socket.h>
 
 #include <net/if.h>
@@ -157,6 +158,7 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, 
uint32_t peerid, uid_t uid)
        struct vmd_if           *vif;
        struct vmop_create_params *vmc = &vm->vm_params;
        struct vm_create_params *vcp = &vmc->vmc_params;
+       struct stat              stat_buf;
        unsigned int             i;
        int                      fd = -1, vmboot = 0;
        int                      kernfd = -1, *diskfds = NULL, *tapfds = NULL;
@@ -225,6 +227,19 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, 
uint32_t peerid, uid_t uid)
 
        /* Open disk images for child */
        for (i = 0 ; i < vcp->vcp_ndisks; i++) {
+                /* Stat disk[i] to ensure it is a regular file */
+                if (stat(vcp->vcp_disks[i], &stat_buf) == -1) {
+                       log_warn("%s: can't open disk %s", __func__,
+                           vcp->vcp_disks[i]);
+                       errno = VMD_DISK_MISSING;
+                       goto fail;
+                }
+                if (S_ISREG(stat_buf.st_mode) == 0) {
+                       log_warn("%s: disk %s is not a regular file", __func__,
+                           vcp->vcp_disks[i]);
+                       errno = VMD_DISK_INVALID;
+                       goto fail;
+                }
                if ((diskfds[i] =
                    open(vcp->vcp_disks[i], O_RDWR)) == -1) {
                        log_warn("%s: can't open disk %s", __func__,
diff --git usr.sbin/vmd/vmd.h usr.sbin/vmd/vmd.h
index 57bdb71cd5f..daeffa7c80e 100644
--- usr.sbin/vmd/vmd.h
+++ usr.sbin/vmd/vmd.h
@@ -53,6 +53,7 @@
 /* vmd -> vmctl error codes */
 #define VMD_BIOS_MISSING       1001
 #define VMD_DISK_MISSING       1002
+#define VMD_DISK_INVALID       1003
 
 /* 100.64.0.0/10 from rfc6598 (IPv4 Prefix for Shared Address Space) */
 #define VMD_DHCP_PREFIX                "100.64.0.0/10"
-- 
2.14.1

Reply via email to