diff options
author | Patrick Tjin <pattjin@google.com> | 2015-12-09 21:17:56 -0800 |
---|---|---|
committer | Simon Shields <keepcalm444@gmail.com> | 2016-03-12 22:33:03 +1100 |
commit | 0a7a34f29e714624c5de103e82d4bb18be88b7dc (patch) | |
tree | 1001820238589e4216f7a0311c2f086394adecd7 /drivers/net/wireless | |
parent | d75110451e7c79cbe3daf0a0088331b7021e8627 (diff) | |
download | kernel_samsung_smdk4412-0a7a34f29e714624c5de103e82d4bb18be88b7dc.zip kernel_samsung_smdk4412-0a7a34f29e714624c5de103e82d4bb18be88b7dc.tar.gz kernel_samsung_smdk4412-0a7a34f29e714624c5de103e82d4bb18be88b7dc.tar.bz2 |
net: wireless: bcmdhd: check packet length for event messages
Check the datalen field is less than the size of
packet received from the network.
BUG=25306181
BUG=25668859
Signed-off-by: Patrick Tjin <pattjin@google.com>
Change-Id: I3b021d88a95bd7d4e6e0d745d2527d73487bcadc
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_common.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_linux.c | 7 |
3 files changed, 15 insertions, 5 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h index b0b2b29..c5074ab 100644 --- a/drivers/net/wireless/bcmdhd/dhd.h +++ b/drivers/net/wireless/bcmdhd/dhd.h @@ -651,7 +651,7 @@ extern int dhd_ifname2idx(struct dhd_info *dhd, char *name); 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, +extern int wl_host_event(dhd_pub_t *dhd_pub, int *idx, void *pktdata, size_t pktlen, wl_event_msg_t *, void **data_ptr); extern void wl_event_to_host_order(wl_event_msg_t * evt); diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c index ea3433e..dd6ace7 100644 --- a/drivers/net/wireless/bcmdhd/dhd_common.c +++ b/drivers/net/wireless/bcmdhd/dhd_common.c @@ -1190,7 +1190,7 @@ wl_show_host_event(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) { /* check whether packet is a BRCM event pkt */ @@ -1211,6 +1211,9 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, return (BCME_ERROR); } + if (pktlen < sizeof(bcm_event_t)) + return (BCME_ERROR); + *data_ptr = &pvt_data[1]; event_data = *data_ptr; @@ -1220,8 +1223,14 @@ wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, type = ntoh32_ua((void *)&event->event_type); flags = ntoh16_ua((void *)&event->flags); status = ntoh32_ua((void *)&event->status); + datalen = ntoh32_ua((void *)&event->datalen); + if (datalen > pktlen) + return (BCME_ERROR); + evlen = datalen + sizeof(bcm_event_t); + if (evlen > pktlen) + return (BCME_ERROR); switch (type) { #ifdef PROP_TXSTATUS diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c index da6b2a2..876ae18 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux.c @@ -679,7 +679,7 @@ static int dhd_toe_get(dhd_info_t *dhd, int idx, uint32 *toe_ol); 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, +static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, size_t pktlen, wl_event_msg_t *event_ptr, void **data_ptr); #if defined(SUPPORT_P2P_GO_PS) @@ -2213,6 +2213,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan) #else skb->mac.raw, #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) */ + len - 2, &event, &data); @@ -6154,13 +6155,13 @@ dhd_get_wireless_stats(struct net_device *dev) #endif /* defined(WL_WIRELESS_EXT) */ static int -dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, +dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, size_t pktlen, wl_event_msg_t *event, void **data) { int bcmerror = 0; ASSERT(dhd != NULL); - bcmerror = wl_host_event(&dhd->pub, ifidx, pktdata, event, data); + bcmerror = wl_host_event(&dhd->pub, ifidx, pktdata, pktlen, event, data); if (bcmerror != BCME_OK) return (bcmerror); |