]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: tas2783A: Fix issues in firmware parsing
authorNiranjan H Y <niranjan.hy@ti.com>
Thu, 30 Oct 2025 15:16:37 +0000 (20:46 +0530)
committerMark Brown <broonie@kernel.org>
Thu, 6 Nov 2025 13:12:34 +0000 (13:12 +0000)
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: 4cc9bd8d7b32 (ASoc: tas2783A: Add soundwire based codec driver)
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <error27@gmail.com>
Closes: https://lore.kernel.org/r/202510291226.2R3fbYNh-lkp@intel.com/
Signed-off-by: Niranjan H Y <niranjan.hy@ti.com>
Link: https://patch.msgid.link/20251030151637.566-1-niranjan.hy@ti.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/tas2783-sdw.c

index 1fb4227b711e6b6d29fc3cfce6daa431c41f7f55..e273b80d033e18ae66ed6a1965a147510d2ca7aa 100644 (file)
@@ -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,7 +823,8 @@ static void tas2783_fw_ready(const struct firmware *fmw, void *context)
                        break;
        }
        mutex_unlock(&tas_dev->pde_lock);
-       tas2783_update_calibdata(tas_dev);
+       if (!ret)
+               tas2783_update_calibdata(tas_dev);
 
 out:
        if (!ret)