aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/328-v4.17-0001-brcmfmac-fix-firmware-request-processing-if-nvram-lo.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/328-v4.17-0001-brcmfmac-fix-firmware-request-processing-if-nvram-lo.patch')
-rw-r--r--package/kernel/mac80211/patches/328-v4.17-0001-brcmfmac-fix-firmware-request-processing-if-nvram-lo.patch81
1 files changed, 81 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/328-v4.17-0001-brcmfmac-fix-firmware-request-processing-if-nvram-lo.patch b/package/kernel/mac80211/patches/328-v4.17-0001-brcmfmac-fix-firmware-request-processing-if-nvram-lo.patch
new file mode 100644
index 0000000000..cd2279dd65
--- /dev/null
+++ b/package/kernel/mac80211/patches/328-v4.17-0001-brcmfmac-fix-firmware-request-processing-if-nvram-lo.patch
@@ -0,0 +1,81 @@
+From 0b5c0305e57ca940713bcb2b202fd2b412c62f31 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Tue, 3 Apr 2018 10:18:15 +0200
+Subject: [PATCH] brcmfmac: fix firmware request processing if nvram load fails
+
+When nvram loading fails a double free occurred. Fix this and reorg the
+code a little.
+
+Fixes: d09ae51a4b67 ("brcmfmac: pass struct in brcmf_fw_get_firmwares()")
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../broadcom/brcm80211/brcmfmac/firmware.c | 36 ++++++++++++----------
+ 1 file changed, 20 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+@@ -459,7 +459,7 @@ static void brcmf_fw_free_request(struct
+ kfree(req);
+ }
+
+-static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
++static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
+ {
+ struct brcmf_fw *fwctx = ctx;
+ struct brcmf_fw_item *cur;
+@@ -498,13 +498,10 @@ static void brcmf_fw_request_nvram_done(
+ brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length);
+ cur->nv_data.data = nvram;
+ cur->nv_data.len = nvram_length;
+- return;
++ return 0;
+
+ fail:
+- brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
+- fwctx->done(fwctx->dev, -ENOENT, NULL);
+- brcmf_fw_free_request(fwctx->req);
+- kfree(fwctx);
++ return -ENOENT;
+ }
+
+ static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async)
+@@ -553,20 +550,27 @@ static void brcmf_fw_request_done(const
+ brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path,
+ fw ? "" : "not ");
+
+- if (fw) {
+- if (cur->type == BRCMF_FW_TYPE_BINARY)
+- cur->binary = fw;
+- else if (cur->type == BRCMF_FW_TYPE_NVRAM)
+- brcmf_fw_request_nvram_done(fw, fwctx);
+- else
+- release_firmware(fw);
+- } else if (cur->type == BRCMF_FW_TYPE_NVRAM) {
+- brcmf_fw_request_nvram_done(NULL, fwctx);
+- } else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) {
++ if (!fw)
+ ret = -ENOENT;
++
++ switch (cur->type) {
++ case BRCMF_FW_TYPE_NVRAM:
++ ret = brcmf_fw_request_nvram_done(fw, fwctx);
++ break;
++ case BRCMF_FW_TYPE_BINARY:
++ cur->binary = fw;
++ break;
++ default:
++ /* something fishy here so bail out early */
++ brcmf_err("unknown fw type: %d\n", cur->type);
++ release_firmware(fw);
++ ret = -EINVAL;
+ goto fail;
+ }
+
++ if (ret < 0 && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
++ goto fail;
++
+ do {
+ if (++fwctx->curpos == fwctx->req->n_items) {
+ ret = 0;