From owner-svn-src-head@freebsd.org Mon Sep 5 03:21:32 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E183CAC46C2; Mon, 5 Sep 2016 03:21:32 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BF939157; Mon, 5 Sep 2016 03:21:32 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u853LWad069330; Mon, 5 Sep 2016 03:21:32 GMT (envelope-from sephe@FreeBSD.org) Received: (from sephe@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u853LVYa069328; Mon, 5 Sep 2016 03:21:31 GMT (envelope-from sephe@FreeBSD.org) Message-Id: <201609050321.u853LVYa069328@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sephe set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau Date: Mon, 5 Sep 2016 03:21:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r305405 - head/sys/dev/hyperv/vmbus X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 05 Sep 2016 03:21:33 -0000 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;