summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorArend Van Spriel <arend.vanspriel@broadcom.com>2017-09-12 04:47:53 -0400
committerKalle Valo <kvalo@codeaurora.org>2017-09-20 00:46:29 -0400
commit17df6453d4be17910456e99c5a85025aa1b7a246 (patch)
treeef84bc921d2e6fda33f14a1c5e3af899674bbc33 /drivers/net/wireless
parent4c707c04f622a7a8570a8db6389e5a2310b92195 (diff)
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 <cernekee@chromium.org> Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> Reviewed-by: Franky Lin <franky.lin@broadcom.com> Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index aaed4ab503ad..26a0de371c26 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3162,6 +3162,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3162 struct brcmf_cfg80211_info *cfg = ifp->drvr->config; 3162 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3163 s32 status; 3163 s32 status;
3164 struct brcmf_escan_result_le *escan_result_le; 3164 struct brcmf_escan_result_le *escan_result_le;
3165 u32 escan_buflen;
3165 struct brcmf_bss_info_le *bss_info_le; 3166 struct brcmf_bss_info_le *bss_info_le;
3166 struct brcmf_bss_info_le *bss = NULL; 3167 struct brcmf_bss_info_le *bss = NULL;
3167 u32 bi_length; 3168 u32 bi_length;
@@ -3181,11 +3182,23 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3181 3182
3182 if (status == BRCMF_E_STATUS_PARTIAL) { 3183 if (status == BRCMF_E_STATUS_PARTIAL) {
3183 brcmf_dbg(SCAN, "ESCAN Partial result\n"); 3184 brcmf_dbg(SCAN, "ESCAN Partial result\n");
3185 if (e->datalen < sizeof(*escan_result_le)) {
3186 brcmf_err("invalid event data length\n");
3187 goto exit;
3188 }
3184 escan_result_le = (struct brcmf_escan_result_le *) data; 3189 escan_result_le = (struct brcmf_escan_result_le *) data;
3185 if (!escan_result_le) { 3190 if (!escan_result_le) {
3186 brcmf_err("Invalid escan result (NULL pointer)\n"); 3191 brcmf_err("Invalid escan result (NULL pointer)\n");
3187 goto exit; 3192 goto exit;
3188 } 3193 }
3194 escan_buflen = le32_to_cpu(escan_result_le->buflen);
3195 if (escan_buflen > BRCMF_ESCAN_BUF_SIZE ||
3196 escan_buflen > e->datalen ||
3197 escan_buflen < sizeof(*escan_result_le)) {
3198 brcmf_err("Invalid escan buffer length: %d\n",
3199 escan_buflen);
3200 goto exit;
3201 }
3189 if (le16_to_cpu(escan_result_le->bss_count) != 1) { 3202 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3190 brcmf_err("Invalid bss_count %d: ignoring\n", 3203 brcmf_err("Invalid bss_count %d: ignoring\n",
3191 escan_result_le->bss_count); 3204 escan_result_le->bss_count);
@@ -3202,9 +3215,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3202 } 3215 }
3203 3216
3204 bi_length = le32_to_cpu(bss_info_le->length); 3217 bi_length = le32_to_cpu(bss_info_le->length);
3205 if (bi_length != (le32_to_cpu(escan_result_le->buflen) - 3218 if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
3206 WL_ESCAN_RESULTS_FIXED_SIZE)) { 3219 brcmf_err("Ignoring invalid bss_info length: %d\n",
3207 brcmf_err("Invalid bss_info length %d: ignoring\n",
3208 bi_length); 3220 bi_length);
3209 goto exit; 3221 goto exit;
3210 } 3222 }