Skip to content

Commit 0b5c030

Browse files
Arend Van SprielKalle Valo
authored andcommitted
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: d09ae51 ("brcmfmac: pass struct in brcmf_fw_get_firmwares()") Reported-by: Dan Carpenter <[email protected]> Signed-off-by: Arend van Spriel <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent 4608f06 commit 0b5c030

File tree

1 file changed

+20
-16
lines changed
  • drivers/net/wireless/broadcom/brcm80211/brcmfmac

1 file changed

+20
-16
lines changed

drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ static void brcmf_fw_free_request(struct brcmf_fw_request *req)
459459
kfree(req);
460460
}
461461

462-
static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
462+
static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
463463
{
464464
struct brcmf_fw *fwctx = ctx;
465465
struct brcmf_fw_item *cur;
@@ -498,13 +498,10 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
498498
brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length);
499499
cur->nv_data.data = nvram;
500500
cur->nv_data.len = nvram_length;
501-
return;
501+
return 0;
502502

503503
fail:
504-
brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
505-
fwctx->done(fwctx->dev, -ENOENT, NULL);
506-
brcmf_fw_free_request(fwctx->req);
507-
kfree(fwctx);
504+
return -ENOENT;
508505
}
509506

510507
static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async)
@@ -553,20 +550,27 @@ static void brcmf_fw_request_done(const struct firmware *fw, void *ctx)
553550
brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path,
554551
fw ? "" : "not ");
555552

556-
if (fw) {
557-
if (cur->type == BRCMF_FW_TYPE_BINARY)
558-
cur->binary = fw;
559-
else if (cur->type == BRCMF_FW_TYPE_NVRAM)
560-
brcmf_fw_request_nvram_done(fw, fwctx);
561-
else
562-
release_firmware(fw);
563-
} else if (cur->type == BRCMF_FW_TYPE_NVRAM) {
564-
brcmf_fw_request_nvram_done(NULL, fwctx);
565-
} else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) {
553+
if (!fw)
566554
ret = -ENOENT;
555+
556+
switch (cur->type) {
557+
case BRCMF_FW_TYPE_NVRAM:
558+
ret = brcmf_fw_request_nvram_done(fw, fwctx);
559+
break;
560+
case BRCMF_FW_TYPE_BINARY:
561+
cur->binary = fw;
562+
break;
563+
default:
564+
/* something fishy here so bail out early */
565+
brcmf_err("unknown fw type: %d\n", cur->type);
566+
release_firmware(fw);
567+
ret = -EINVAL;
567568
goto fail;
568569
}
569570

571+
if (ret < 0 && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
572+
goto fail;
573+
570574
do {
571575
if (++fwctx->curpos == fwctx->req->n_items) {
572576
ret = 0;

0 commit comments

Comments
 (0)