diff options
Diffstat (limited to 'package/kernel/mac80211/patches/344-0005-brcmfmac-Add-length-checks-on-firmware-events.patch')
-rw-r--r-- | package/kernel/mac80211/patches/344-0005-brcmfmac-Add-length-checks-on-firmware-events.patch | 283 |
1 files changed, 0 insertions, 283 deletions
diff --git a/package/kernel/mac80211/patches/344-0005-brcmfmac-Add-length-checks-on-firmware-events.patch b/package/kernel/mac80211/patches/344-0005-brcmfmac-Add-length-checks-on-firmware-events.patch deleted file mode 100644 index 3e2e3503b6..0000000000 --- a/package/kernel/mac80211/patches/344-0005-brcmfmac-Add-length-checks-on-firmware-events.patch +++ /dev/null @@ -1,283 +0,0 @@ -From: Hante Meuleman <meuleman@broadcom.com> -Date: Wed, 17 Feb 2016 11:26:54 +0100 -Subject: [PATCH] brcmfmac: Add length checks on firmware events - -Add additional length checks on firmware events to create more -robust code. - -Reviewed-by: Arend Van Spriel <arend@broadcom.com> -Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> -Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> -Reviewed-by: Lei Zhang <leizh@broadcom.com> -Signed-off-by: Hante Meuleman <meuleman@broadcom.com> -Signed-off-by: Arend van Spriel <arend@broadcom.com> -Signed-off-by: Kalle Valo <kvalo@codeaurora.org> ---- - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -3092,6 +3092,11 @@ brcmf_notify_sched_scan_results(struct b - - brcmf_dbg(SCAN, "Enter\n"); - -+ if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) { -+ brcmf_dbg(SCAN, "Event data to small. Ignore\n"); -+ return 0; -+ } -+ - if (e->event_code == BRCMF_E_PFN_NET_LOST) { - brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n"); - return 0; -@@ -3415,6 +3420,11 @@ brcmf_wowl_nd_results(struct brcmf_if *i - - brcmf_dbg(SCAN, "Enter\n"); - -+ if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) { -+ brcmf_dbg(SCAN, "Event data to small. Ignore\n"); -+ return 0; -+ } -+ - pfn_result = (struct brcmf_pno_scanresults_le *)data; - - if (e->event_code == BRCMF_E_PFN_NET_LOST) { ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c -@@ -26,50 +26,6 @@ - #include "fwil.h" - - /** -- * struct brcm_ethhdr - broadcom specific ether header. -- * -- * @subtype: subtype for this packet. -- * @length: TODO: length of appended data. -- * @version: version indication. -- * @oui: OUI of this packet. -- * @usr_subtype: subtype for this OUI. -- */ --struct brcm_ethhdr { -- __be16 subtype; -- __be16 length; -- u8 version; -- u8 oui[3]; -- __be16 usr_subtype; --} __packed; -- --struct brcmf_event_msg_be { -- __be16 version; -- __be16 flags; -- __be32 event_type; -- __be32 status; -- __be32 reason; -- __be32 auth_type; -- __be32 datalen; -- u8 addr[ETH_ALEN]; -- char ifname[IFNAMSIZ]; -- u8 ifidx; -- u8 bsscfgidx; --} __packed; -- --/** -- * struct brcmf_event - contents of broadcom event packet. -- * -- * @eth: standard ether header. -- * @hdr: broadcom specific ether header. -- * @msg: common part of the actual event message. -- */ --struct brcmf_event { -- struct ethhdr eth; -- struct brcm_ethhdr hdr; -- struct brcmf_event_msg_be msg; --} __packed; -- --/** - * struct brcmf_fweh_queue_item - event item on event queue. - * - * @q: list element for queuing. -@@ -85,6 +41,7 @@ struct brcmf_fweh_queue_item { - u8 ifidx; - u8 ifaddr[ETH_ALEN]; - struct brcmf_event_msg_be emsg; -+ u32 datalen; - u8 data[0]; - }; - -@@ -294,6 +251,11 @@ static void brcmf_fweh_event_worker(stru - brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data, - min_t(u32, emsg.datalen, 64), - "event payload, len=%d\n", emsg.datalen); -+ if (emsg.datalen > event->datalen) { -+ brcmf_err("event invalid length header=%d, msg=%d\n", -+ event->datalen, emsg.datalen); -+ goto event_free; -+ } - - /* special handling of interface event */ - if (event->code == BRCMF_E_IF) { -@@ -439,7 +401,8 @@ int brcmf_fweh_activate_events(struct br - * dispatch the event to a registered handler (using worker). - */ - void brcmf_fweh_process_event(struct brcmf_pub *drvr, -- struct brcmf_event *event_packet) -+ struct brcmf_event *event_packet, -+ u32 packet_len) - { - enum brcmf_fweh_event_code code; - struct brcmf_fweh_info *fweh = &drvr->fweh; -@@ -459,6 +422,9 @@ void brcmf_fweh_process_event(struct brc - if (code != BRCMF_E_IF && !fweh->evt_handler[code]) - return; - -+ if (datalen > BRCMF_DCMD_MAXLEN) -+ return; -+ - if (in_interrupt()) - alloc_flag = GFP_ATOMIC; - -@@ -472,6 +438,7 @@ void brcmf_fweh_process_event(struct brc - /* use memcpy to get aligned event message */ - memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); - memcpy(event->data, data, datalen); -+ event->datalen = datalen; - memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN); - - brcmf_fweh_queue_event(fweh, event); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h -@@ -27,7 +27,6 @@ - struct brcmf_pub; - struct brcmf_if; - struct brcmf_cfg80211_info; --struct brcmf_event; - - /* list of firmware events */ - #define BRCMF_FWEH_EVENT_ENUM_DEFLIST \ -@@ -180,13 +179,55 @@ enum brcmf_fweh_event_code { - /** - * definitions for event packet validation. - */ --#define BRCMF_EVENT_OUI_OFFSET 19 --#define BRCM_OUI "\x00\x10\x18" --#define DOT11_OUI_LEN 3 --#define BCMILCP_BCM_SUBTYPE_EVENT 1 -+#define BRCM_OUI "\x00\x10\x18" -+#define BCMILCP_BCM_SUBTYPE_EVENT 1 - - - /** -+ * struct brcm_ethhdr - broadcom specific ether header. -+ * -+ * @subtype: subtype for this packet. -+ * @length: TODO: length of appended data. -+ * @version: version indication. -+ * @oui: OUI of this packet. -+ * @usr_subtype: subtype for this OUI. -+ */ -+struct brcm_ethhdr { -+ __be16 subtype; -+ __be16 length; -+ u8 version; -+ u8 oui[3]; -+ __be16 usr_subtype; -+} __packed; -+ -+struct brcmf_event_msg_be { -+ __be16 version; -+ __be16 flags; -+ __be32 event_type; -+ __be32 status; -+ __be32 reason; -+ __be32 auth_type; -+ __be32 datalen; -+ u8 addr[ETH_ALEN]; -+ char ifname[IFNAMSIZ]; -+ u8 ifidx; -+ u8 bsscfgidx; -+} __packed; -+ -+/** -+ * struct brcmf_event - contents of broadcom event packet. -+ * -+ * @eth: standard ether header. -+ * @hdr: broadcom specific ether header. -+ * @msg: common part of the actual event message. -+ */ -+struct brcmf_event { -+ struct ethhdr eth; -+ struct brcm_ethhdr hdr; -+ struct brcmf_event_msg_be msg; -+} __packed; -+ -+/** - * struct brcmf_event_msg - firmware event message. - * - * @version: version information. -@@ -256,34 +297,35 @@ void brcmf_fweh_unregister(struct brcmf_ - enum brcmf_fweh_event_code code); - int brcmf_fweh_activate_events(struct brcmf_if *ifp); - void brcmf_fweh_process_event(struct brcmf_pub *drvr, -- struct brcmf_event *event_packet); -+ struct brcmf_event *event_packet, -+ u32 packet_len); - void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing); - - static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, - struct sk_buff *skb) - { - struct brcmf_event *event_packet; -- u8 *data; - u16 usr_stype; - - /* only process events when protocol matches */ - if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) - return; - -+ if ((skb->len + ETH_HLEN) < sizeof(*event_packet)) -+ return; -+ - /* check for BRCM oui match */ - event_packet = (struct brcmf_event *)skb_mac_header(skb); -- data = (u8 *)event_packet; -- data += BRCMF_EVENT_OUI_OFFSET; -- if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN)) -+ if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0], -+ sizeof(event_packet->hdr.oui))) - return; - - /* final match on usr_subtype */ -- data += DOT11_OUI_LEN; -- usr_stype = get_unaligned_be16(data); -+ usr_stype = get_unaligned_be16(&event_packet->hdr.usr_subtype); - if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT) - return; - -- brcmf_fweh_process_event(drvr, event_packet); -+ brcmf_fweh_process_event(drvr, event_packet, skb->len + ETH_HLEN); - } - - #endif /* FWEH_H_ */ ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -@@ -1361,6 +1361,11 @@ int brcmf_p2p_notify_action_frame_rx(str - u16 mgmt_type; - u8 action; - -+ if (e->datalen < sizeof(*rxframe)) { -+ brcmf_dbg(SCAN, "Event data to small. Ignore\n"); -+ return 0; -+ } -+ - ch.chspec = be16_to_cpu(rxframe->chanspec); - cfg->d11inf.decchspec(&ch); - /* Check if wpa_supplicant has registered for this frame */ -@@ -1858,6 +1863,11 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere - brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code, - e->reason); - -+ if (e->datalen < sizeof(*rxframe)) { -+ brcmf_dbg(SCAN, "Event data to small. Ignore\n"); -+ return 0; -+ } -+ - ch.chspec = be16_to_cpu(rxframe->chanspec); - cfg->d11inf.decchspec(&ch); - |