mac80211: brcmfmac: backport important changes from the 4.13
[openwrt/openwrt.git] / package / kernel / mac80211 / patches / 326-brcmfmac-add-length-check-in-brcmf_cfg80211_escan_ha.patch
1 From: Arend Van Spriel <arend.vanspriel@broadcom.com>
2 Date: Tue, 12 Sep 2017 10:47:53 +0200
3 Subject: [PATCH] brcmfmac: add length check in brcmf_cfg80211_escan_handler()
4
5 Upon handling the firmware notification for scans the length was
6 checked properly and may result in corrupting kernel heap memory
7 due to buffer overruns. This fix addresses CVE-2017-0786.
8
9 Cc: stable@vger.kernel.org # v4.0.x
10 Cc: Kevin Cernekee <cernekee@chromium.org>
11 Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
12 Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
13 Reviewed-by: Franky Lin <franky.lin@broadcom.com>
14 Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
15 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
16 ---
17
18 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
19 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
20 @@ -3088,6 +3088,7 @@ brcmf_cfg80211_escan_handler(struct brcm
21 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
22 s32 status;
23 struct brcmf_escan_result_le *escan_result_le;
24 + u32 escan_buflen;
25 struct brcmf_bss_info_le *bss_info_le;
26 struct brcmf_bss_info_le *bss = NULL;
27 u32 bi_length;
28 @@ -3107,11 +3108,23 @@ brcmf_cfg80211_escan_handler(struct brcm
29
30 if (status == BRCMF_E_STATUS_PARTIAL) {
31 brcmf_dbg(SCAN, "ESCAN Partial result\n");
32 + if (e->datalen < sizeof(*escan_result_le)) {
33 + brcmf_err("invalid event data length\n");
34 + goto exit;
35 + }
36 escan_result_le = (struct brcmf_escan_result_le *) data;
37 if (!escan_result_le) {
38 brcmf_err("Invalid escan result (NULL pointer)\n");
39 goto exit;
40 }
41 + escan_buflen = le32_to_cpu(escan_result_le->buflen);
42 + if (escan_buflen > BRCMF_ESCAN_BUF_SIZE ||
43 + escan_buflen > e->datalen ||
44 + escan_buflen < sizeof(*escan_result_le)) {
45 + brcmf_err("Invalid escan buffer length: %d\n",
46 + escan_buflen);
47 + goto exit;
48 + }
49 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
50 brcmf_err("Invalid bss_count %d: ignoring\n",
51 escan_result_le->bss_count);
52 @@ -3128,9 +3141,8 @@ brcmf_cfg80211_escan_handler(struct brcm
53 }
54
55 bi_length = le32_to_cpu(bss_info_le->length);
56 - if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
57 - WL_ESCAN_RESULTS_FIXED_SIZE)) {
58 - brcmf_err("Invalid bss_info length %d: ignoring\n",
59 + if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
60 + brcmf_err("Ignoring invalid bss_info length: %d\n",
61 bi_length);
62 goto exit;
63 }