Unverified Commit 84f5526e authored by Niranjan H Y's avatar Niranjan H Y Committed by Mark Brown
Browse files

ASoC: tas2783A: Fix issues in firmware parsing



During firmware download, if the size of the firmware is too small,
it wrongly assumes the firmware download is successful. If there is
size mismatch with chunk's header, invalid memory is accessed.
Fix these issues by throwing error during these cases.

Fixes: 4cc9bd8d (ASoc: tas2783A: Add soundwire based codec driver)
Reported-by: default avatarkernel test robot <lkp@intel.com>
Reported-by: default avatarDan Carpenter <error27@gmail.com>
Closes: https://lore.kernel.org/r/202510291226.2R3fbYNh-lkp@intel.com/


Signed-off-by: default avatarNiranjan H Y <niranjan.hy@ti.com>
Link: https://patch.msgid.link/20251030151637.566-1-niranjan.hy@ti.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 1a58d865
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -762,10 +762,17 @@ static void tas2783_fw_ready(const struct firmware *fmw, void *context)
		goto out;
	}

	mutex_lock(&tas_dev->pde_lock);
	img_sz = fmw->size;
	buf = fmw->data;
	offset += FW_DL_OFFSET;
	if (offset >= (img_sz - FW_FL_HDR)) {
		dev_err(tas_dev->dev,
			"firmware is too small");
		ret = -EINVAL;
		goto out;
	}

	mutex_lock(&tas_dev->pde_lock);
	while (offset < (img_sz - FW_FL_HDR)) {
		memset(&hdr, 0, sizeof(hdr));
		offset += read_header(&buf[offset], &hdr);
@@ -776,6 +783,14 @@ static void tas2783_fw_ready(const struct firmware *fmw, void *context)
		/* size also includes the header */
		file_blk_size = hdr.length - FW_FL_HDR;

		/* make sure that enough data is there */
		if (offset + file_blk_size > img_sz) {
			ret = -EINVAL;
			dev_err(tas_dev->dev,
				"corrupt firmware file");
			break;
		}

		switch (hdr.file_id) {
		case 0:
			ret = sdw_nwrite_no_pm(tas_dev->sdw_peripheral,
@@ -808,6 +823,7 @@ static void tas2783_fw_ready(const struct firmware *fmw, void *context)
			break;
	}
	mutex_unlock(&tas_dev->pde_lock);
	if (!ret)
		tas2783_update_calibdata(tas_dev);

out: