svn commit: r305405 - head/sys/dev/hyperv/vmbus
Sepherosa Ziehau
sephe at FreeBSD.org
Mon Sep 5 03:21:33 UTC 2016
Author: sephe
Date: Mon Sep 5 03:21:31 2016
New Revision: 305405
URL: https://svnweb.freebsd.org/changeset/base/305405
Log:
hyperv/vmbus: Stringent header length and total length check.
While I'm here, minor style changes.
MFC after: 1 week
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7752
Modified:
head/sys/dev/hyperv/vmbus/vmbus_chan.c
head/sys/dev/hyperv/vmbus/vmbus_reg.h
Modified: head/sys/dev/hyperv/vmbus/vmbus_chan.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_chan.c Mon Sep 5 02:00:35 2016 (r305404)
+++ head/sys/dev/hyperv/vmbus/vmbus_chan.c Mon Sep 5 03:21:31 2016 (r305405)
@@ -721,7 +721,20 @@ vmbus_chan_recv(struct vmbus_channel *ch
error = vmbus_rxbr_peek(&chan->ch_rxbr, &pkt, sizeof(pkt));
if (error)
- return error;
+ return (error);
+
+ if (__predict_false(pkt.cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) {
+ device_printf(chan->ch_dev, "invalid hlen %u\n",
+ pkt.cph_hlen);
+ /* XXX this channel is dead actually. */
+ return (EIO);
+ }
+ if (__predict_false(pkt.cph_hlen > pkt.cph_tlen)) {
+ device_printf(chan->ch_dev, "invalid hlen %u and tlen %u\n",
+ pkt.cph_hlen, pkt.cph_tlen);
+ /* XXX this channel is dead actually. */
+ return (EIO);
+ }
hlen = VMBUS_CHANPKT_GETLEN(pkt.cph_hlen);
dlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen) - hlen;
@@ -729,7 +742,7 @@ vmbus_chan_recv(struct vmbus_channel *ch
if (*dlen0 < dlen) {
/* Return the size of this packet's data. */
*dlen0 = dlen;
- return ENOBUFS;
+ return (ENOBUFS);
}
*xactid = pkt.cph_xactid;
@@ -739,7 +752,7 @@ vmbus_chan_recv(struct vmbus_channel *ch
error = vmbus_rxbr_read(&chan->ch_rxbr, data, dlen, hlen);
KASSERT(!error, ("vmbus_rxbr_read failed"));
- return 0;
+ return (0);
}
int
@@ -751,13 +764,26 @@ vmbus_chan_recv_pkt(struct vmbus_channel
error = vmbus_rxbr_peek(&chan->ch_rxbr, &pkt, sizeof(pkt));
if (error)
- return error;
+ return (error);
+
+ if (__predict_false(pkt.cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) {
+ device_printf(chan->ch_dev, "invalid hlen %u\n",
+ pkt.cph_hlen);
+ /* XXX this channel is dead actually. */
+ return (EIO);
+ }
+ if (__predict_false(pkt.cph_hlen > pkt.cph_tlen)) {
+ device_printf(chan->ch_dev, "invalid hlen %u and tlen %u\n",
+ pkt.cph_hlen, pkt.cph_tlen);
+ /* XXX this channel is dead actually. */
+ return (EIO);
+ }
pktlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen);
if (*pktlen0 < pktlen) {
/* Return the size of this packet. */
*pktlen0 = pktlen;
- return ENOBUFS;
+ return (ENOBUFS);
}
*pktlen0 = pktlen;
@@ -765,7 +791,7 @@ vmbus_chan_recv_pkt(struct vmbus_channel
error = vmbus_rxbr_read(&chan->ch_rxbr, pkt0, pktlen, 0);
KASSERT(!error, ("vmbus_rxbr_read failed"));
- return 0;
+ return (0);
}
static void
Modified: head/sys/dev/hyperv/vmbus/vmbus_reg.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_reg.h Mon Sep 5 02:00:35 2016 (r305404)
+++ head/sys/dev/hyperv/vmbus/vmbus_reg.h Mon Sep 5 03:21:31 2016 (r305405)
@@ -153,6 +153,9 @@ do { \
#define VMBUS_CHANPKT_TOTLEN(tlen) \
roundup2((tlen), VMBUS_CHANPKT_SIZE_ALIGN)
+#define VMBUS_CHANPKT_HLEN_MIN \
+ (sizeof(struct vmbus_chanpkt_hdr) >> VMBUS_CHANPKT_SIZE_SHIFT)
+
struct vmbus_chanpkt {
struct vmbus_chanpkt_hdr cp_hdr;
} __packed;
More information about the svn-src-all
mailing list