diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h index 7c29a33813f874071389f80e61bf8caafedfc599..02a9f43065c7e06e6035b9aa6715c3ddbb07004d 100644 --- a/drivers/net/wireless/bcmdhd/dhd.h +++ b/drivers/net/wireless/bcmdhd/dhd.h @@ -726,7 +726,7 @@ extern int dhd_net2idx(struct dhd_info *dhd, struct net_device *net); extern struct net_device * dhd_idx2net(void *pub, int ifidx); extern int net_os_send_hang_message(struct net_device *dev); extern int wl_host_event(dhd_pub_t *dhd_pub, int *idx, void *pktdata, - wl_event_msg_t *, void **data_ptr, void *); + size_t pktlen, wl_event_msg_t *, void **data_ptr, void *); extern void wl_event_to_host_order(wl_event_msg_t * evt); extern int dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int len); diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c index 1ed11d64c7579fadeb0b337d1b787f6d650cd477..d6f31a97757771a0311c5b65e6f0ba9446824543 100644 --- a/drivers/net/wireless/bcmdhd/dhd_common.c +++ b/drivers/net/wireless/bcmdhd/dhd_common.c @@ -1592,7 +1592,7 @@ wl_show_host_event(dhd_pub_t *dhd_pub, wl_event_msg_t *event, void *event_data, #endif /* SHOW_EVENTS */ int -wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, +wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, size_t pktlen, wl_event_msg_t *event, void **data_ptr, void *raw_event) { /* check whether packet is a BRCM event pkt */ @@ -1626,6 +1626,9 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, status = ntoh32_ua((void *)&event->status); datalen = ntoh32_ua((void *)&event->datalen); evlen = datalen + sizeof(bcm_event_t); + if (evlen > pktlen) { + return (BCME_ERROR); + } /* find equivalent host index for event ifidx */ hostidx = dhd_ifidx2hostidx(dhd_pub->info, event->ifidx); diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c index dcc8704f3f6b362b6111b12a141cb330cd13184f..d55ff65c713308e95ca83abb4bd3b22a4985b691 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux.c @@ -692,7 +692,7 @@ static int dhd_toe_set(dhd_info_t *dhd, int idx, uint32 toe_ol); #endif /* TOE */ static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event_ptr, void **data_ptr); + size_t pktlen, wl_event_msg_t *event_ptr, void **data_ptr); #ifdef DHD_UNICAST_DHCP static const uint8 llc_snap_hdr[SNAP_HDR_LEN] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; static int dhd_get_pkt_ip_type(dhd_pub_t *dhd, void *skb, uint8 **data_ptr, @@ -2763,13 +2763,15 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) /* Process special event packets and then discard them */ memset(&event, 0, sizeof(event)); - if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) { + if ((ntoh16(skb->protocol) == ETHER_TYPE_BRCM) && + (len >= sizeof(bcm_event_t))) { dhd_wl_host_event(dhd, &ifidx, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) skb_mac_header(skb), #else skb->mac.raw, #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) */ + len, &event, &data); @@ -6943,15 +6945,17 @@ dhd_get_wireless_stats(struct net_device *dev) static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event, void **data) + size_t pktlen, wl_event_msg_t *event, void **data) { int bcmerror = 0; ASSERT(dhd != NULL); #ifdef SHOW_LOGTRACE - bcmerror = wl_host_event(&dhd->pub, ifidx, pktdata, event, data, &dhd->event_data); + bcmerror = wl_host_event(&dhd->pub, ifidx, pktdata, pktlen, + event, data, &dhd->event_data); #else - bcmerror = wl_host_event(&dhd->pub, ifidx, pktdata, event, data, NULL); + bcmerror = wl_host_event(&dhd->pub, ifidx, pktdata, pktlen, + event, data, NULL); #endif /* SHOW_LOGTRACE */ if (bcmerror != BCME_OK)