Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Sep 2016 03:21:31 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r305405 - head/sys/dev/hyperv/vmbus
Message-ID:  <201609050321.u853LVYa069328@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609050321.u853LVYa069328>