summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordv <dv@cvs.openbsd.org>2021-04-21 18:27:37 +0000
committerdv <dv@cvs.openbsd.org>2021-04-21 18:27:37 +0000
commit6dffc02b46300231035fbaca16cc4eb281345af3 (patch)
treebe332e5fef2d917800ae3a44c09770f1cb0d0012
parent247390cd5e4086723f7bd857d0f00d1a71da740f (diff)
Fix packet size checks and remove bad casts.
Because dhcpsz was an uninitialized ssize_t, it was possible that a garbage "packet" would be queued on the receiving end of the virtio network device. Change the type to size_t and add proper checks based on it being greater than zero. Remove the cast of ssize_t to uint64_t that also caused garbage sizes when dhcpsz was unintialized and set at runtime to something < 0.
-rw-r--r--usr.sbin/vmd/virtio.c16
-rw-r--r--usr.sbin/vmd/virtio.h4
2 files changed, 13 insertions, 7 deletions
diff --git a/usr.sbin/vmd/virtio.c b/usr.sbin/vmd/virtio.c
index f937bf602f6..9fcb752ea4d 100644
--- a/usr.sbin/vmd/virtio.c
+++ b/usr.sbin/vmd/virtio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: virtio.c,v 1.84 2021/03/29 23:37:01 dv Exp $ */
+/* $OpenBSD: virtio.c,v 1.85 2021/04/21 18:27:36 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -1075,7 +1075,7 @@ vionet_update_qs(struct vionet_dev *dev)
* Must be called with dev->mutex acquired.
*/
int
-vionet_enq_rx(struct vionet_dev *dev, char *pkt, ssize_t sz, int *spc)
+vionet_enq_rx(struct vionet_dev *dev, char *pkt, size_t sz, int *spc)
{
uint64_t q_gpa;
uint32_t vr_sz;
@@ -1083,7 +1083,7 @@ vionet_enq_rx(struct vionet_dev *dev, char *pkt, ssize_t sz, int *spc)
ptrdiff_t off;
int ret;
char *vr;
- ssize_t rem;
+ size_t rem;
struct vring_desc *desc, *pkt_desc, *hdr_desc;
struct vring_avail *avail;
struct vring_used *used;
@@ -1092,6 +1092,11 @@ vionet_enq_rx(struct vionet_dev *dev, char *pkt, ssize_t sz, int *spc)
ret = 0;
+ if (sz < 1) {
+ log_warn("%s: invalid packet size", __func__);
+ return (0);
+ }
+
if (!(dev->cfg.device_status & VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK))
return ret;
@@ -1162,7 +1167,7 @@ vionet_enq_rx(struct vionet_dev *dev, char *pkt, ssize_t sz, int *spc)
}
} else {
/* Fallback to pkt_desc descriptor */
- if ((uint64_t)pkt_desc->len >= (uint64_t)sz) {
+ if (pkt_desc->len >= sz) {
/* Must be not readable */
if ((pkt_desc->flags & VRING_DESC_F_WRITE) == 0) {
log_warnx("unexpected readable rx desc %d",
@@ -1231,7 +1236,7 @@ vionet_rx(struct vionet_dev *dev)
if (errno != EAGAIN)
log_warn("unexpected read error on vionet "
"device");
- } else if (sz != 0) {
+ } else if (sz > 0) {
eh = (struct ether_header *)buf;
if (!dev->lockedmac || sz < ETHER_HDR_LEN ||
ETHER_IS_MULTICAST(eh->ether_dhost) ||
@@ -1402,6 +1407,7 @@ vionet_notify_tx(struct vionet_dev *dev)
struct vring_used *used;
struct ether_header *eh;
+ dhcpsz = 0;
vr = pkt = dhcppkt = NULL;
ret = spc = 0;
diff --git a/usr.sbin/vmd/virtio.h b/usr.sbin/vmd/virtio.h
index 9d7ef81831d..d39bc5c6672 100644
--- a/usr.sbin/vmd/virtio.h
+++ b/usr.sbin/vmd/virtio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: virtio.h,v 1.37 2021/03/29 23:37:01 dv Exp $ */
+/* $OpenBSD: virtio.h,v 1.38 2021/04/21 18:27:36 dv Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -298,7 +298,7 @@ int vionet_notifyq(struct vionet_dev *);
void vionet_notify_rx(struct vionet_dev *);
int vionet_notify_tx(struct vionet_dev *);
void vionet_process_rx(uint32_t);
-int vionet_enq_rx(struct vionet_dev *, char *, ssize_t, int *);
+int vionet_enq_rx(struct vionet_dev *, char *, size_t, int *);
void vionet_set_hostmac(struct vmd_vm *, unsigned int, uint8_t *);
int vmmci_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);