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;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to