svn commit: r305411 - head/sys/dev/hyperv/netvsc
Sepherosa Ziehau
sephe at FreeBSD.org
Mon Sep 5 05:07:42 UTC 2016
Author: sephe
Date: Mon Sep 5 05:07:40 2016
New Revision: 305411
URL: https://svnweb.freebsd.org/changeset/base/305411
Log:
hyperv/hn: Stringent RNDIS control message length check.
MFC after: 1 week
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D7758
Modified:
head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
head/sys/dev/hyperv/netvsc/hv_rndis_filter.h
Modified: head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_rndis_filter.c Mon Sep 5 04:56:56 2016 (r305410)
+++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.c Mon Sep 5 05:07:40 2016 (r305411)
@@ -72,7 +72,7 @@ __FBSDID("$FreeBSD$");
* Forward declarations
*/
static void hv_rf_receive_indicate_status(struct hn_softc *sc,
- const rndis_msg *response);
+ const void *data, int dlen);
static void hv_rf_receive_data(struct hn_rx_ring *rxr,
const void *data, int dlen);
static int hv_rf_query_device_mac(struct hn_softc *sc, uint8_t *eaddr);
@@ -131,21 +131,29 @@ hv_set_rppi_data(rndis_msg *rndis_mesg,
* RNDIS filter receive indicate status
*/
static void
-hv_rf_receive_indicate_status(struct hn_softc *sc, const rndis_msg *response)
+hv_rf_receive_indicate_status(struct hn_softc *sc, const void *data, int dlen)
{
- const rndis_indicate_status *indicate = &response->msg.indicate_status;
-
- switch(indicate->status) {
+ const struct rndis_status_msg *msg;
+
+ if (dlen < sizeof(*msg)) {
+ if_printf(sc->hn_ifp, "invalid RNDIS status\n");
+ return;
+ }
+ msg = data;
+
+ switch (msg->rm_status) {
case RNDIS_STATUS_MEDIA_CONNECT:
netvsc_linkstatus_callback(sc, 1);
break;
+
case RNDIS_STATUS_MEDIA_DISCONNECT:
netvsc_linkstatus_callback(sc, 0);
break;
+
default:
/* TODO: */
- if_printf(sc->hn_ifp,
- "unknown status %d received\n", indicate->status);
+ if_printf(sc->hn_ifp, "unknown RNDIS status 0x%08x\n",
+ msg->rm_status);
break;
}
}
@@ -283,34 +291,41 @@ hv_rf_receive_data(struct hn_rx_ring *rx
/*
* RNDIS filter on receive
*/
-int
+void
hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
const void *data, int dlen)
{
- const rndis_msg *rndis_hdr;
const struct rndis_comp_hdr *comp;
+ const struct rndis_msghdr *hdr;
+
+ if (__predict_false(dlen < sizeof(*hdr))) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS msg\n");
+ return;
+ }
+ hdr = data;
- rndis_hdr = data;
- switch (rndis_hdr->ndis_msg_type) {
- /* data message */
+ switch (hdr->rm_type) {
case REMOTE_NDIS_PACKET_MSG:
hv_rf_receive_data(rxr, data, dlen);
break;
- /* completion messages */
case REMOTE_NDIS_INITIALIZE_CMPLT:
case REMOTE_NDIS_QUERY_CMPLT:
case REMOTE_NDIS_SET_CMPLT:
- case REMOTE_NDIS_KEEPALIVE_CMPLT:
+ case REMOTE_NDIS_KEEPALIVE_CMPLT: /* unused */
+ if (dlen < sizeof(*comp)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS cmplt\n");
+ return;
+ }
comp = data;
+
KASSERT(comp->rm_rid > HN_RNDIS_RID_COMPAT_MAX,
- ("invalid rid 0x%08x\n", comp->rm_rid));
+ ("invalid RNDIS rid 0x%08x\n", comp->rm_rid));
vmbus_xact_ctx_wakeup(sc->hn_xact, comp, dlen);
break;
- /* notification message */
case REMOTE_NDIS_INDICATE_STATUS_MSG:
- hv_rf_receive_indicate_status(sc, rndis_hdr);
+ hv_rf_receive_indicate_status(sc, data, dlen);
break;
case REMOTE_NDIS_RESET_CMPLT:
@@ -321,15 +336,14 @@ hv_rf_on_receive(struct hn_softc *sc, st
* RESET is not issued by hn(4), so this message should
* _not_ be observed.
*/
- if_printf(sc->hn_ifp, "RESET CMPLT received\n");
+ if_printf(rxr->hn_ifp, "RESET cmplt received\n");
break;
default:
- if_printf(sc->hn_ifp, "unknown RNDIS message 0x%x\n",
- rndis_hdr->ndis_msg_type);
+ if_printf(rxr->hn_ifp, "unknown RNDIS msg 0x%x\n",
+ hdr->rm_type);
break;
}
- return (0);
}
/*
Modified: head/sys/dev/hyperv/netvsc/hv_rndis_filter.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_rndis_filter.h Mon Sep 5 04:56:56 2016 (r305410)
+++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.h Mon Sep 5 05:07:40 2016 (r305411)
@@ -40,7 +40,7 @@
*/
struct hn_rx_ring;
-int hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
+void hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
const void *data, int dlen);
void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr);
int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int *nchan,
More information about the svn-src-all
mailing list