Commit 6721969c authored by Arend Van Spriel's avatar Arend Van Spriel Committed by Greg Kroah-Hartman

brcmfmac: add length check in brcmf_cfg80211_escan_handler()

commit 17df6453 upstream.

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: Kevin Cernekee <cernekee@chromium.org>
Reviewed-by: default avatarHante Meuleman <hante.meuleman@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: default avatarFranky Lin <franky.lin@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 69f53f5d
...@@ -2903,6 +2903,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, ...@@ -2903,6 +2903,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
struct brcmf_cfg80211_info *cfg = ifp->drvr->config; struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
s32 status; s32 status;
struct brcmf_escan_result_le *escan_result_le; 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_info_le;
struct brcmf_bss_info_le *bss = NULL; struct brcmf_bss_info_le *bss = NULL;
u32 bi_length; u32 bi_length;
...@@ -2919,11 +2920,23 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, ...@@ -2919,11 +2920,23 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
if (status == BRCMF_E_STATUS_PARTIAL) { if (status == BRCMF_E_STATUS_PARTIAL) {
brcmf_dbg(SCAN, "ESCAN Partial result\n"); 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; escan_result_le = (struct brcmf_escan_result_le *) data;
if (!escan_result_le) { if (!escan_result_le) {
brcmf_err("Invalid escan result (NULL pointer)\n"); brcmf_err("Invalid escan result (NULL pointer)\n");
goto exit; goto exit;
} }
escan_buflen = le32_to_cpu(escan_result_le->buflen);
if (escan_buflen > WL_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) { if (le16_to_cpu(escan_result_le->bss_count) != 1) {
brcmf_err("Invalid bss_count %d: ignoring\n", brcmf_err("Invalid bss_count %d: ignoring\n",
escan_result_le->bss_count); escan_result_le->bss_count);
...@@ -2940,9 +2953,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, ...@@ -2940,9 +2953,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
} }
bi_length = le32_to_cpu(bss_info_le->length); bi_length = le32_to_cpu(bss_info_le->length);
if (bi_length != (le32_to_cpu(escan_result_le->buflen) - if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
WL_ESCAN_RESULTS_FIXED_SIZE)) { brcmf_err("Ignoring invalid bss_info length: %d\n",
brcmf_err("Invalid bss_info length %d: ignoring\n",
bi_length); bi_length);
goto exit; goto exit;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment