diff mbox

ASoC: wm_adsp: Fix validation of firmware and coeff lengths

Message ID 20171207211928.btwtwlfci6f4hku2@xylophone.i.decadent.org.uk (mailing list archive)
State Accepted
Commit 50dd2ea8ef67a1617e0c0658bcbec4b9fb03b936
Headers show

Commit Message

Ben Hutchings Dec. 7, 2017, 9:19 p.m. UTC
The checks for whether another region/block header could be present
are subtracting the size from the current offset.  Obviously we should
instead subtract the offset from the size.

The checks for whether the region/block data fit in the file are
adding the data size to the current offset and header size, without
checking for integer overflow.  Rearrange these so that overflow is
impossible.

Cc: stable@vger.kernel.org
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
---
 sound/soc/codecs/wm_adsp.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

Comments

Charles Keepax Dec. 8, 2017, 9:36 a.m. UTC | #1
On Thu, Dec 07, 2017 at 09:19:29PM +0000, Ben Hutchings wrote:
> The checks for whether another region/block header could be present
> are subtracting the size from the current offset.  Obviously we should
> instead subtract the offset from the size.
> 
> The checks for whether the region/block data fit in the file are
> adding the data size to the current offset and header size, without
> checking for integer overflow.  Rearrange these so that overflow is
> impossible.
> 
> Cc: stable@vger.kernel.org
> Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
> ---

Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Tested-by: Charles Keepax <ckeepax@opensource.cirrus.com>

But you would probably be best to resend and include Mark Brown
in the To: field. He applies the Wolfson patches directly to his
tree and he might miss it since it just went to the list.

Thanks,
Charles
diff mbox

Patch

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 65c059b5ffd7..66e32f5d2917 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -1733,7 +1733,7 @@  static int wm_adsp_load(struct wm_adsp *dsp)
 		 le64_to_cpu(footer->timestamp));
 
 	while (pos < firmware->size &&
-	       pos - firmware->size > sizeof(*region)) {
+	       sizeof(*region) < firmware->size - pos) {
 		region = (void *)&(firmware->data[pos]);
 		region_name = "Unknown";
 		reg = 0;
@@ -1782,8 +1782,8 @@  static int wm_adsp_load(struct wm_adsp *dsp)
 			 regions, le32_to_cpu(region->len), offset,
 			 region_name);
 
-		if ((pos + le32_to_cpu(region->len) + sizeof(*region)) >
-		    firmware->size) {
+		if (le32_to_cpu(region->len) >
+		    firmware->size - pos - sizeof(*region)) {
 			adsp_err(dsp,
 				 "%s.%d: %s region len %d bytes exceeds file length %zu\n",
 				 file, regions, region_name,
@@ -2253,7 +2253,7 @@  static int wm_adsp_load_coeff(struct wm_adsp *dsp)
 
 	blocks = 0;
 	while (pos < firmware->size &&
-	       pos - firmware->size > sizeof(*blk)) {
+	       sizeof(*blk) < firmware->size - pos) {
 		blk = (void *)(&firmware->data[pos]);
 
 		type = le16_to_cpu(blk->type);
@@ -2327,8 +2327,8 @@  static int wm_adsp_load_coeff(struct wm_adsp *dsp)
 		}
 
 		if (reg) {
-			if ((pos + le32_to_cpu(blk->len) + sizeof(*blk)) >
-			    firmware->size) {
+			if (le32_to_cpu(blk->len) >
+			    firmware->size - pos - sizeof(*blk)) {
 				adsp_err(dsp,
 					 "%s.%d: %s region len %d bytes exceeds file length %zu\n",
 					 file, blocks, region_name,