From: Felix Fietkau Date: Mon, 16 Oct 2017 10:46:58 +0000 (+0200) Subject: brcmfmac: backport length check in brcmf_cfg80211_escan_handler() X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=bff16304b0bf;p=openwrt%2Fstaging%2Fhauke.git brcmfmac: backport length check in brcmf_cfg80211_escan_handler() Fixes CVE-2017-0786 Signed-off-by: Felix Fietkau --- diff --git a/package/kernel/mac80211/patches/326-brcmfmac-add-length-check-in-brcmf_cfg80211_escan_ha.patch b/package/kernel/mac80211/patches/326-brcmfmac-add-length-check-in-brcmf_cfg80211_escan_ha.patch new file mode 100644 index 0000000000..63c867a80c --- /dev/null +++ b/package/kernel/mac80211/patches/326-brcmfmac-add-length-check-in-brcmf_cfg80211_escan_ha.patch @@ -0,0 +1,63 @@ +From: Arend Van Spriel +Date: Tue, 12 Sep 2017 10:47:53 +0200 +Subject: [PATCH] brcmfmac: add length check in brcmf_cfg80211_escan_handler() + +Upon handling the firmware notification for scans the length was +checked properly and may result in corrupting kernel heap memory +due to buffer overruns. This fix addresses CVE-2017-0786. + +Cc: stable@vger.kernel.org # v4.0.x +Cc: Kevin Cernekee +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3088,6 +3088,7 @@ brcmf_cfg80211_escan_handler(struct brcm + struct brcmf_cfg80211_info *cfg = ifp->drvr->config; + s32 status; + struct brcmf_escan_result_le *escan_result_le; ++ u32 escan_buflen; + struct brcmf_bss_info_le *bss_info_le; + struct brcmf_bss_info_le *bss = NULL; + u32 bi_length; +@@ -3104,11 +3105,23 @@ brcmf_cfg80211_escan_handler(struct brcm + + if (status == BRCMF_E_STATUS_PARTIAL) { + brcmf_dbg(SCAN, "ESCAN Partial result\n"); ++ if (e->datalen < sizeof(*escan_result_le)) { ++ brcmf_err("invalid event data length\n"); ++ goto exit; ++ } + escan_result_le = (struct brcmf_escan_result_le *) data; + if (!escan_result_le) { + brcmf_err("Invalid escan result (NULL pointer)\n"); + goto exit; + } ++ escan_buflen = le32_to_cpu(escan_result_le->buflen); ++ if (escan_buflen > BRCMF_ESCAN_BUF_SIZE || ++ escan_buflen > e->datalen || ++ escan_buflen < sizeof(*escan_result_le)) { ++ brcmf_err("Invalid escan buffer length: %d\n", ++ escan_buflen); ++ goto exit; ++ } + if (le16_to_cpu(escan_result_le->bss_count) != 1) { + brcmf_err("Invalid bss_count %d: ignoring\n", + escan_result_le->bss_count); +@@ -3125,9 +3138,8 @@ brcmf_cfg80211_escan_handler(struct brcm + } + + bi_length = le32_to_cpu(bss_info_le->length); +- if (bi_length != (le32_to_cpu(escan_result_le->buflen) - +- WL_ESCAN_RESULTS_FIXED_SIZE)) { +- brcmf_err("Invalid bss_info length %d: ignoring\n", ++ if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) { ++ brcmf_err("Ignoring invalid bss_info length: %d\n", + bi_length); + goto exit; + }