The maximum length of the value is extended to 64k bytes.
authorasou <asou@openbsd.org>
Sat, 7 Jan 2023 06:40:21 +0000 (06:40 +0000)
committerasou <asou@openbsd.org>
Sat, 7 Jan 2023 06:40:21 +0000 (06:40 +0000)
ok yasuoka

share/man/man4/pvbus.4
sys/dev/pv/hypervic.c
sys/dev/pv/pvbus.c
sys/dev/pv/pvvar.h
sys/dev/pv/vmt.c
sys/dev/pv/xenstore.c
usr.sbin/hostctl/hostctl.c

index 8d67809..33b6a22 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: pvbus.4,v 1.14 2017/06/14 12:42:09 jmc Exp $
+.\"    $OpenBSD: pvbus.4,v 1.15 2023/01/07 06:40:21 asou Exp $
 .\"
 .\" Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
 .\" Copyright (c) 2006 Jason McIntyre <jmc@openbsd.org>
@@ -15,7 +15,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: June 14 2017 $
+.Dd $Mdocdate: January 7 2023 $
 .Dt PVBUS 4
 .Os
 .Sh NAME
@@ -125,6 +125,13 @@ Read the value from
 .Fa pvr_key
 and return it in
 .Fa pvr_value .
+If
+.Fa pvr_valuelen
+is not enough for the value,
+the command will fail and
+.Xr errno 2
+is set to
+.Er ERANGE .
 .It Dv PVBUSIOC_KVTYPE
 Return the type of the attached hypervisor interface as a string in
 .Fa pvr_key ;
index 9c7f70d..a7455d0 100644 (file)
@@ -1151,11 +1151,12 @@ hv_kvop(void *arg, int op, char *key, char *val, size_t vallen)
        kvpl = &kvp->kvp_pool[pool];
        if (strlen(key) == 0) {
                for (next = 0; next < MAXPOOLENTS; next++) {
-                       if ((val + vallen < vp + HV_KVP_MAX_KEY_SIZE / 2) ||
-                           kvp_pool_keys(kvpl, next, vp, &keylen))
+                       if (val + vallen < vp + HV_KVP_MAX_KEY_SIZE / 2)
+                               return (ERANGE);
+                       if (kvp_pool_keys(kvpl, next, vp, &keylen))
                                goto out;
                        if (strlcat(val, "\n", vallen) >= vallen)
-                               goto out;
+                               return (ERANGE);
                        vp += keylen;
                }
  out:
index 5f7c4b5..2f4cdd3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pvbus.c,v 1.26 2022/12/08 05:45:36 yasuoka Exp $      */
+/*     $OpenBSD: pvbus.c,v 1.27 2023/01/07 06:40:21 asou Exp $ */
 
 /*
  * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -399,13 +399,14 @@ pvbusgetstr(size_t srclen, const char *src, char **dstp)
 
        /*
         * Reject size that is too short or obviously too long:
-        * - at least one byte for the nul terminator.
-        * - PAGE_SIZE is an arbitrary value, but known pv backends seem
-        *   to have a hard (PAGE_SIZE - x) limit in their messaging.
+        * - Known pv backends other than vmware have a hard limit smaller than
+        *   PVBUS_KVOP_MAXSIZE in their messaging.  vmware has a software
+        *   limit at 1MB, but current open-vm-tools has a limit at 64KB
+        *   (=PVBUS_KVOP_MAXSIZE).
         */
        if (srclen < 1)
                return (EINVAL);
-       else if (srclen > PAGE_SIZE)
+       else if (srclen > PVBUS_KVOP_MAXSIZE)
                return (ENAMETOOLONG);
 
        *dstp = dst = malloc(srclen + 1, M_TEMP, M_WAITOK | M_ZERO);
index 4e23ae5..d2ba273 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pvvar.h,v 1.10 2017/06/22 06:21:12 jmatthew Exp $     */
+/*     $OpenBSD: pvvar.h,v 1.11 2023/01/07 06:40:21 asou Exp $ */
 
 /*
  * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -30,6 +30,8 @@ struct pvbus_req {
 #define PVBUSIOC_KVWRITE       _IOWR('V', 2, struct pvbus_req)
 #define PVBUSIOC_TYPE          _IOWR('V', 3, struct pvbus_req)
 
+#define        PVBUS_KVOP_MAXSIZE      (64 * 1024)
+
 #ifdef _KERNEL
 enum {
        PVBUS_KVM,
index c2c1cd3..569b860 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vmt.c,v 1.29 2022/12/28 10:11:36 asou Exp $ */
+/*     $OpenBSD: vmt.c,v 1.30 2023/01/07 06:40:21 asou Exp $ */
 
 /*
  * Copyright (c) 2007 David Crawshaw <david@zentus.com>
@@ -547,7 +547,7 @@ vmt_kvop(void *arg, int op, char *key, char *value, size_t valuelen)
 
        if (rlen > 0) {
                if (rlen + 1 > valuelen) {
-                       error = EMSGSIZE;
+                       error = ERANGE;
                        goto close;
                }
 
index 494eb40..1f4c230 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: xenstore.c,v 1.47 2022/11/10 02:47:52 asou Exp $      */
+/*     $OpenBSD: xenstore.c,v 1.48 2023/01/07 06:40:21 asou Exp $      */
 
 /*
  * Copyright (c) 2015 Mike Belopuhov
@@ -1116,11 +1116,16 @@ xs_kvop(void *xsc, int op, char *key, char *value, size_t valuelen)
                /* FALLTHROUGH */
        case XS_LIST:
                for (i = 0; i < iov_cnt; i++) {
-                       if (i && strlcat(value, "\n", valuelen) >= valuelen)
+                       if (i > 0 && strlcat(value, "\n", valuelen) >=
+                           valuelen) {
+                               error = ERANGE;
                                break;
+                       }
                        if (strlcat(value, iovp[i].iov_base,
-                           valuelen) >= valuelen)
+                           valuelen) >= valuelen) {
+                               error = ERANGE;
                                break;
+                       }
                }
                xs_resfree(&xst, iovp, iov_cnt);
                break;
@@ -1128,5 +1133,5 @@ xs_kvop(void *xsc, int op, char *key, char *value, size_t valuelen)
                break;
        }
 
-       return (0);
+       return (error);
 }
index f0639dd..a6b6c72 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: hostctl.c,v 1.5 2019/06/28 13:32:47 deraadt Exp $     */
+/*     $OpenBSD: hostctl.c,v 1.6 2023/01/07 06:40:21 asou Exp $        */
 
 /*
  * Copyright (c) 2016 Reyk Floeter <reyk@openbsd.org>
@@ -178,15 +178,29 @@ main(int argc, char *argv[])
                usage();
 
        /* Re-open read-writable */
-       if (cmd == PVBUSIOC_KVWRITE) {
+       if (cmd != PVBUSIOC_KVREAD) {
                close(fd);
                if ((fd = open(path_pvbus, O_RDWR)) == -1)
                        err(1, "open: %s", path_pvbus);
+               if ((ret = ioctl(fd, cmd, &pvr, sizeof(pvr))) == -1)
+                       err(1, "ioctl");
+       } else {
+               while (1) {
+                       if ((ret = ioctl(fd, cmd, &pvr, sizeof(pvr))) == 0)
+                               break;
+                       if (errno == ERANGE &&
+                           pvr.pvr_valuelen < PVBUS_KVOP_MAXSIZE) {
+                               /* the buffer is not enough, expand it */
+                               pvr.pvr_valuelen *= 2;
+                               if ((pvr.pvr_value = realloc(pvr.pvr_value,
+                                   pvr.pvr_valuelen)) == NULL)
+                                       err(1, "realloc");
+                               continue;
+                       }
+                       err(1, "ioctl");
+               }
        }
 
-       if ((ret = ioctl(fd, cmd, &pvr, sizeof(pvr))) == -1)
-               err(1, "ioctl");
-
        if (!qflag && strlen(pvr.pvr_value)) {
                /*
                 * The value can contain newlines and basically anything;