328-v4.17-0001-brcmfmac-fix-firmware-request-processing-if-nvram-lo.patch 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. From 0b5c0305e57ca940713bcb2b202fd2b412c62f31 Mon Sep 17 00:00:00 2001
  2. From: Arend Van Spriel <[email protected]>
  3. Date: Tue, 3 Apr 2018 10:18:15 +0200
  4. Subject: [PATCH] brcmfmac: fix firmware request processing if nvram load fails
  5. When nvram loading fails a double free occurred. Fix this and reorg the
  6. code a little.
  7. Fixes: d09ae51a4b67 ("brcmfmac: pass struct in brcmf_fw_get_firmwares()")
  8. Reported-by: Dan Carpenter <[email protected]>
  9. Signed-off-by: Arend van Spriel <[email protected]>
  10. Signed-off-by: Kalle Valo <[email protected]>
  11. ---
  12. .../broadcom/brcm80211/brcmfmac/firmware.c | 36 ++++++++++++----------
  13. 1 file changed, 20 insertions(+), 16 deletions(-)
  14. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
  15. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
  16. @@ -459,7 +459,7 @@ static void brcmf_fw_free_request(struct
  17. kfree(req);
  18. }
  19. -static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
  20. +static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
  21. {
  22. struct brcmf_fw *fwctx = ctx;
  23. struct brcmf_fw_item *cur;
  24. @@ -498,13 +498,10 @@ static void brcmf_fw_request_nvram_done(
  25. brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length);
  26. cur->nv_data.data = nvram;
  27. cur->nv_data.len = nvram_length;
  28. - return;
  29. + return 0;
  30. fail:
  31. - brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
  32. - fwctx->done(fwctx->dev, -ENOENT, NULL);
  33. - brcmf_fw_free_request(fwctx->req);
  34. - kfree(fwctx);
  35. + return -ENOENT;
  36. }
  37. static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async)
  38. @@ -553,20 +550,27 @@ static void brcmf_fw_request_done(const
  39. brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path,
  40. fw ? "" : "not ");
  41. - if (fw) {
  42. - if (cur->type == BRCMF_FW_TYPE_BINARY)
  43. - cur->binary = fw;
  44. - else if (cur->type == BRCMF_FW_TYPE_NVRAM)
  45. - brcmf_fw_request_nvram_done(fw, fwctx);
  46. - else
  47. - release_firmware(fw);
  48. - } else if (cur->type == BRCMF_FW_TYPE_NVRAM) {
  49. - brcmf_fw_request_nvram_done(NULL, fwctx);
  50. - } else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) {
  51. + if (!fw)
  52. ret = -ENOENT;
  53. +
  54. + switch (cur->type) {
  55. + case BRCMF_FW_TYPE_NVRAM:
  56. + ret = brcmf_fw_request_nvram_done(fw, fwctx);
  57. + break;
  58. + case BRCMF_FW_TYPE_BINARY:
  59. + cur->binary = fw;
  60. + break;
  61. + default:
  62. + /* something fishy here so bail out early */
  63. + brcmf_err("unknown fw type: %d\n", cur->type);
  64. + release_firmware(fw);
  65. + ret = -EINVAL;
  66. goto fail;
  67. }
  68. + if (ret < 0 && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
  69. + goto fail;
  70. +
  71. do {
  72. if (++fwctx->curpos == fwctx->req->n_items) {
  73. ret = 0;