Refactor vm_instance to return error value directly.
authordv <dv@openbsd.org>
Wed, 5 May 2021 21:33:11 +0000 (21:33 +0000)
committerdv <dv@openbsd.org>
Wed, 5 May 2021 21:33:11 +0000 (21:33 +0000)
vmd(8)'s vm_instance function set unsupported errno values. Change the
api to directly return an error (either errno or custom vmd error).

"go for it" -mlarkin@

usr.sbin/vmd/vmd.c

index 6ae9862..1138148 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vmd.c,v 1.124 2021/05/04 10:36:01 dv Exp $    */
+/*     $OpenBSD: vmd.c,v 1.125 2021/05/05 21:33:11 dv Exp $    */
 
 /*
  * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -1268,10 +1268,13 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc,
        unsigned int             i, j;
        struct vmd_switch       *sw;
        char                    *s;
+       int                      ret = 0;
 
        /* Check if this is an instance of another VM */
-       if (vm_instance(ps, &vm_parent, vmc, uid) == -1)
+       if ((ret = vm_instance(ps, &vm_parent, vmc, uid)) != 0) {
+               errno = ret; /* XXX might set invalid errno */
                return (-1);
+       }
 
        errno = 0;
        *ret_vm = NULL;
@@ -1427,11 +1430,9 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
                return (0);
 
        if ((*vm_parent = vm_getbyname(vmc->vmc_instance)) == NULL) {
-               errno = VMD_PARENT_INVALID;
-               return (-1);
+               return (VMD_PARENT_INVALID);
        }
 
-       errno = 0;
        vmcp = &(*vm_parent)->vm_params;
        vcpp = &vmcp->vmc_params;
 
@@ -1439,8 +1440,7 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
        if (vm_checkperm(NULL, &vmcp->vmc_insowner, uid) != 0) {
                log_warnx("vm \"%s\" no permission to create vm instance",
                    vcpp->vcp_name);
-               errno = ENAMETOOLONG;
-               return (-1);
+               return (ENAMETOOLONG);
        }
 
        id = vcp->vcp_id;
@@ -1448,8 +1448,7 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
 
        if ((vm = vm_getbyname(vcp->vcp_name)) != NULL ||
            (vm = vm_getbyvmid(vcp->vcp_id)) != NULL) {
-               errno = EPROCLIM;
-               return (-1);
+               return (EPROCLIM);
        }
 
        /* CPU */
@@ -1458,8 +1457,7 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
        if (vm_checkinsflag(vmcp, VMOP_CREATE_CPU, uid) != 0 &&
            vcp->vcp_ncpus != vcpp->vcp_ncpus) {
                log_warnx("vm \"%s\" no permission to set cpus", name);
-               errno = EPERM;
-               return (-1);
+               return (EPERM);
        }
 
        /* memory */
@@ -1470,16 +1468,14 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
            vcp->vcp_memranges[0].vmr_size !=
            vcpp->vcp_memranges[0].vmr_size) {
                log_warnx("vm \"%s\" no permission to set memory", name);
-               errno = EPERM;
-               return (-1);
+               return (EPERM);
        }
 
        /* disks cannot be inherited */
        if (vm_checkinsflag(vmcp, VMOP_CREATE_DISK, uid) != 0 &&
            vcp->vcp_ndisks) {
                log_warnx("vm \"%s\" no permission to set disks", name);
-               errno = EPERM;
-               return (-1);
+               return (EPERM);
        }
        for (i = 0; i < vcp->vcp_ndisks; i++) {
                /* Check if this disk is already used in the parent */
@@ -1488,8 +1484,7 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
                            vcpp->vcp_disks[j]) == 0) {
                                log_warnx("vm \"%s\" disk %s cannot be reused",
                                    name, vcp->vcp_disks[i]);
-                               errno = EBUSY;
-                               return (-1);
+                               return (EBUSY);
                        }
                }
                vmc->vmc_checkaccess |= VMOP_CREATE_DISK;
@@ -1500,8 +1495,7 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
            vm_checkinsflag(vmcp, VMOP_CREATE_NETWORK, uid) != 0 &&
            vcp->vcp_nnics != vcpp->vcp_nnics) {
                log_warnx("vm \"%s\" no permission to set interfaces", name);
-               errno = EPERM;
-               return (-1);
+               return (EPERM);
        }
        for (i = 0; i < vcpp->vcp_nnics; i++) {
                /* Interface got overwritten */
@@ -1529,16 +1523,14 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
                            sizeof(vcp->vcp_macs[i])) != 0) {
                                log_warnx("vm \"%s\" lladdr cannot be reused",
                                    name);
-                               errno = EBUSY;
-                               return (-1);
+                               return (EBUSY);
                        }
                        if (strlen(vmc->vmc_ifnames[i]) &&
                            strcmp(vmc->vmc_ifnames[i],
                            vmcp->vmc_ifnames[j]) == 0) {
                                log_warnx("vm \"%s\" %s cannot be reused",
                                    vmc->vmc_ifnames[i], name);
-                               errno = EBUSY;
-                               return (-1);
+                               return (EBUSY);
                        }
                }
        }
@@ -1548,30 +1540,26 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
                if (vm_checkinsflag(vmcp, VMOP_CREATE_KERNEL, uid) != 0) {
                        log_warnx("vm \"%s\" no permission to set boot image",
                            name);
-                       errno = EPERM;
-                       return (-1);
+                       return (EPERM);
                }
                vmc->vmc_checkaccess |= VMOP_CREATE_KERNEL;
        } else if (strlcpy(vcp->vcp_kernel, vcpp->vcp_kernel,
            sizeof(vcp->vcp_kernel)) >= sizeof(vcp->vcp_kernel)) {
                log_warnx("vm \"%s\" kernel name too long", name);
-               errno = EINVAL;
-               return (-1);
+               return (EINVAL);
        }
 
        /* cdrom */
        if (strlen(vcp->vcp_cdrom) > 0) {
                if (vm_checkinsflag(vmcp, VMOP_CREATE_CDROM, uid) != 0) {
                        log_warnx("vm \"%s\" no permission to set cdrom", name);
-                       errno = EPERM;
-                       return (-1);
+                       return (EPERM);
                }
                vmc->vmc_checkaccess |= VMOP_CREATE_CDROM;
        } else if (strlcpy(vcp->vcp_cdrom, vcpp->vcp_cdrom,
            sizeof(vcp->vcp_cdrom)) >= sizeof(vcp->vcp_cdrom)) {
                log_warnx("vm \"%s\" cdrom name too long", name);
-               errno = EINVAL;
-               return (-1);
+               return (EINVAL);
        }
 
        /* user */
@@ -1580,8 +1568,7 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
        else if (vmc->vmc_owner.uid != uid &&
            vmc->vmc_owner.uid != vmcp->vmc_owner.uid) {
                log_warnx("vm \"%s\" user mismatch", name);
-               errno = EPERM;
-               return (-1);
+               return (EPERM);
        }
 
        /* group */
@@ -1589,15 +1576,13 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
                vmc->vmc_owner.gid = vmcp->vmc_owner.gid;
        else if (vmc->vmc_owner.gid != vmcp->vmc_owner.gid) {
                log_warnx("vm \"%s\" group mismatch", name);
-               errno = EPERM;
-               return (-1);
+               return (EPERM);
        }
 
        /* child instances */
        if (vmc->vmc_insflags) {
                log_warnx("vm \"%s\" cannot change instance permissions", name);
-               errno = EPERM;
-               return (-1);
+               return (EPERM);
        }
        if (vmcp->vmc_insflags & VMOP_CREATE_INSTANCE) {
                vmc->vmc_insowner.gid = vmcp->vmc_insowner.gid;