326-v4.14-0004-brcmfmac-add-length-check-in-brcmf_cfg80211_escan_ha.patch 2.4 KB

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