summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorASOU Masato <asou@cvs.openbsd.org>2023-01-07 06:40:22 +0000
committerASOU Masato <asou@cvs.openbsd.org>2023-01-07 06:40:22 +0000
commitd90890ed6e363834686d5c3307a6c8688278e2b7 (patch)
tree89b6894587780d9c1ef02e646af63e0a976e3230
parent9232dcce6bb242e47f9429b04e02836e23f9cb03 (diff)
The maximum length of the value is extended to 64k bytes.
ok yasuoka
-rw-r--r--share/man/man4/pvbus.411
-rw-r--r--sys/dev/pv/hypervic.c7
-rw-r--r--sys/dev/pv/pvbus.c11
-rw-r--r--sys/dev/pv/pvvar.h4
-rw-r--r--sys/dev/pv/vmt.c4
-rw-r--r--sys/dev/pv/xenstore.c13
-rw-r--r--usr.sbin/hostctl/hostctl.c24
7 files changed, 52 insertions, 22 deletions
diff --git a/share/man/man4/pvbus.4 b/share/man/man4/pvbus.4
index 8d67809e9c0..33b6a22ea26 100644
--- a/share/man/man4/pvbus.4
+++ b/share/man/man4/pvbus.4
@@ -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 ;
diff --git a/sys/dev/pv/hypervic.c b/sys/dev/pv/hypervic.c
index 9c7f70dd96f..a7455d03e5b 100644
--- a/sys/dev/pv/hypervic.c
+++ b/sys/dev/pv/hypervic.c
@@ -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:
diff --git a/sys/dev/pv/pvbus.c b/sys/dev/pv/pvbus.c
index 5f7c4b57fe0..2f4cdd31849 100644
--- a/sys/dev/pv/pvbus.c
+++ b/sys/dev/pv/pvbus.c
@@ -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);
diff --git a/sys/dev/pv/pvvar.h b/sys/dev/pv/pvvar.h
index 4e23ae52bd5..d2ba273a45a 100644
--- a/sys/dev/pv/pvvar.h
+++ b/sys/dev/pv/pvvar.h
@@ -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,
diff --git a/sys/dev/pv/vmt.c b/sys/dev/pv/vmt.c
index c2c1cd3fa5c..569b8600b03 100644
--- a/sys/dev/pv/vmt.c
+++ b/sys/dev/pv/vmt.c
@@ -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;
}
diff --git a/sys/dev/pv/xenstore.c b/sys/dev/pv/xenstore.c
index 494eb40bfb0..1f4c2307bdd 100644
--- a/sys/dev/pv/xenstore.c
+++ b/sys/dev/pv/xenstore.c
@@ -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);
}
diff --git a/usr.sbin/hostctl/hostctl.c b/usr.sbin/hostctl/hostctl.c
index f0639dd55f3..a6b6c72ea67 100644
--- a/usr.sbin/hostctl/hostctl.c
+++ b/usr.sbin/hostctl/hostctl.c
@@ -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;