Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b5c0305 authored by Arend Van Spriel's avatar Arend Van Spriel Committed by Kalle Valo
Browse files

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: d09ae51a ("brcmfmac: pass struct in brcmf_fw_get_firmwares()")
Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 4608f064
Loading
Loading
Loading
Loading
+20 −16
Original line number Diff line number Diff line
@@ -459,7 +459,7 @@ static void brcmf_fw_free_request(struct brcmf_fw_request *req)
	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(const struct firmware *fw, void *ctx)
	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 struct firmware *fw, void *ctx)
	brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path,
		  fw ? "" : "not ");

	if (fw) {
		if (cur->type == BRCMF_FW_TYPE_BINARY)
	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;
		else if (cur->type == BRCMF_FW_TYPE_NVRAM)
			brcmf_fw_request_nvram_done(fw, fwctx);
		else
		break;
	default:
		/* something fishy here so bail out early */
		brcmf_err("unknown fw type: %d\n", cur->type);
		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)) {
		ret = -ENOENT;
		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;