From 23527ae20b1e20d2a885999cbe908340be6db97f Mon Sep 17 00:00:00 2001 From: Salvatore Bonaccorso Date: Fri, 7 Jun 2019 14:47:57 +0200 Subject: [PATCH] brcmfmac: add subtype check for event handling in data path (CVE-2019-9503) --- debian/changelog | 2 + ...type-check-for-event-handling-in-dat.patch | 106 ++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 109 insertions(+) create mode 100644 debian/patches/bugfix/all/brcmfmac-add-subtype-check-for-event-handling-in-dat.patch diff --git a/debian/changelog b/debian/changelog index b3a35647b..8fb1e59d3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -14,6 +14,8 @@ linux (4.19.37-4) UNRELEASED; urgency=medium [ Salvatore Bonaccorso ] * brcmfmac: assure SSID length from firmware is limited (CVE-2019-9500) + * brcmfmac: add subtype check for event handling in data path + (CVE-2019-9503) -- Ben Hutchings Sun, 19 May 2019 00:04:16 +0100 diff --git a/debian/patches/bugfix/all/brcmfmac-add-subtype-check-for-event-handling-in-dat.patch b/debian/patches/bugfix/all/brcmfmac-add-subtype-check-for-event-handling-in-dat.patch new file mode 100644 index 000000000..0c4910f5e --- /dev/null +++ b/debian/patches/bugfix/all/brcmfmac-add-subtype-check-for-event-handling-in-dat.patch @@ -0,0 +1,106 @@ +From: Arend van Spriel +Date: Thu, 14 Feb 2019 13:43:48 +0100 +Subject: brcmfmac: add subtype check for event handling in data path +Origin: https://git.kernel.org/linus/a4176ec356c73a46c07c181c6d04039fafa34a9f +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-9503 + +For USB there is no separate channel being used to pass events +from firmware to the host driver and as such are passed over the +data path. In order to detect mock event messages an additional +check is needed on event subtype. This check is added conditionally +using unlikely() keyword. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 5 +++-- + .../wireless/broadcom/brcm80211/brcmfmac/fweh.h | 16 ++++++++++++---- + .../broadcom/brcm80211/brcmfmac/msgbuf.c | 2 +- + 3 files changed, 16 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +index e772c0845638..a368ba6e7344 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -519,7 +519,8 @@ void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event) + } else { + /* Process special event packets */ + if (handle_event) +- brcmf_fweh_process_skb(ifp->drvr, skb); ++ brcmf_fweh_process_skb(ifp->drvr, skb, ++ BCMILCP_SUBTYPE_VENDOR_LONG); + + brcmf_netif_rx(ifp, skb); + } +@@ -536,7 +537,7 @@ void brcmf_rx_event(struct device *dev, struct sk_buff *skb) + if (brcmf_rx_hdrpull(drvr, skb, &ifp)) + return; + +- brcmf_fweh_process_skb(ifp->drvr, skb); ++ brcmf_fweh_process_skb(ifp->drvr, skb, 0); + brcmu_pkt_buf_free_skb(skb); + } + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h +index 31f3e8e83a21..7027243db17e 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h +@@ -211,7 +211,7 @@ enum brcmf_fweh_event_code { + */ + #define BRCM_OUI "\x00\x10\x18" + #define BCMILCP_BCM_SUBTYPE_EVENT 1 +- ++#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 + + /** + * struct brcm_ethhdr - broadcom specific ether header. +@@ -334,10 +334,10 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr, + 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 sk_buff *skb, u16 stype) + { + struct brcmf_event *event_packet; +- u16 usr_stype; ++ u16 subtype, usr_stype; + + /* only process events when protocol matches */ + if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) +@@ -346,8 +346,16 @@ static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, + if ((skb->len + ETH_HLEN) < sizeof(*event_packet)) + return; + +- /* check for BRCM oui match */ + event_packet = (struct brcmf_event *)skb_mac_header(skb); ++ ++ /* check subtype if needed */ ++ if (unlikely(stype)) { ++ subtype = get_unaligned_be16(&event_packet->hdr.subtype); ++ if (subtype != stype) ++ return; ++ } ++ ++ /* check for BRCM oui match */ + if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0], + sizeof(event_packet->hdr.oui))) + return; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +index 4e8397a0cbc8..ee922b052561 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -1116,7 +1116,7 @@ static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf) + + skb->protocol = eth_type_trans(skb, ifp->ndev); + +- brcmf_fweh_process_skb(ifp->drvr, skb); ++ brcmf_fweh_process_skb(ifp->drvr, skb, 0); + + exit: + brcmu_pkt_buf_free_skb(skb); +-- +2.20.1 + diff --git a/debian/patches/series b/debian/patches/series index 94c4903cd..47d1b11eb 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -213,6 +213,7 @@ bugfix/all/spec/0029-Documentation-Correct-the-possible-MDS-sysfs-values.patch bugfix/all/spec/0030-x86-speculation-mds-Fix-documentation-typo.patch bugfix/all/spec/powerpc-64s-include-cpu-header.patch bugfix/all/brcmfmac-assure-SSID-length-from-firmware-is-limited.patch +bugfix/all/brcmfmac-add-subtype-check-for-event-handling-in-dat.patch # Fix exported symbol versions bugfix/all/module-disable-matching-missing-version-crc.patch