diff mbox series

scsi: ufs: Fix memory corruption by ufshcd_read_desc_param()

Message ID 20210719231127.869088-1-bvanassche@acm.org
State New
Headers show
Series scsi: ufs: Fix memory corruption by ufshcd_read_desc_param() | expand

Commit Message

Bart Van Assche July 19, 2021, 11:11 p.m. UTC
If param_offset > buff_len then the memcpy() statement in
ufshcd_read_desc_param() corrupts memory since it copies
256 + buff_len - param_offset bytes into a buffer with size buff_len.
Since param_offset < 256 this results in writing past the bound of the
output buffer.

Fixes: cbe193f6f093 ("scsi: ufs: Fix potential NULL pointer access during memcpy")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ufs/ufshcd.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

Avri Altman July 20, 2021, 6:45 a.m. UTC | #1
> 

> If param_offset > buff_len then the memcpy() statement in

> ufshcd_read_desc_param() corrupts memory since it copies

> 256 + buff_len - param_offset bytes into a buffer with size buff_len.

> Since param_offset < 256 this results in writing past the bound of the output

> buffer.

param_offset >= buff_len is tested in line 3381?

Thanks,
Avri

> 

> Fixes: cbe193f6f093 ("scsi: ufs: Fix potential NULL pointer access during

> memcpy")

> Signed-off-by: Bart Van Assche <bvanassche@acm.org>

> ---

>  drivers/scsi/ufs/ufshcd.c | 4 +++-

>  1 file changed, 3 insertions(+), 1 deletion(-)

> 

> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index

> 89da2cf2c969..00502ffe9b4a 100644

> --- a/drivers/scsi/ufs/ufshcd.c

> +++ b/drivers/scsi/ufs/ufshcd.c

> @@ -3365,7 +3365,9 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,

> 

>         if (is_kmalloc) {

>                 /* Make sure we don't copy more data than available */

> -               if (param_offset + param_size > buff_len)

> +               if (buff_len < param_offset)

> +                       param_size = 0;

> +               else if (param_offset + param_size > buff_len)

>                         param_size = buff_len - param_offset;

>                 memcpy(param_read_buf, &desc_buf[param_offset], param_size);

>         }
Bart Van Assche July 20, 2021, 4:01 p.m. UTC | #2
On 7/19/21 11:45 PM, Avri Altman wrote:
>> If param_offset > buff_len then the memcpy() statement in

>> ufshcd_read_desc_param() corrupts memory since it copies

>> 256 + buff_len - param_offset bytes into a buffer with size buff_len.

>> Since param_offset < 256 this results in writing past the bound of the output

>> buffer.

>

> param_offset >= buff_len is tested in line 3381?


Hi Avri,

That's correct. However, a few lines lower there is the following code:

ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC,
				desc_id, desc_index, 0,
				desc_buf, &buff_len);

That call may modify (reduce) 'buff_len'. Hence, a second check is needed.

Thanks,

Bart.
Martin K. Petersen July 29, 2021, 3:37 a.m. UTC | #3
On Mon, 19 Jul 2021 16:11:22 -0700, Bart Van Assche wrote:

> If param_offset > buff_len then the memcpy() statement in

> ufshcd_read_desc_param() corrupts memory since it copies

> 256 + buff_len - param_offset bytes into a buffer with size buff_len.

> Since param_offset < 256 this results in writing past the bound of the

> output buffer.


Applied to 5.14/scsi-fixes, thanks!

[1/1] scsi: ufs: Fix memory corruption by ufshcd_read_desc_param()
      https://git.kernel.org/mkp/scsi/c/b1d5de8c6ea2

-- 
Martin K. Petersen	Oracle Linux Engineering
Bean Huo July 29, 2021, 2:05 p.m. UTC | #4
On Wed, 2021-07-28 at 23:37 -0400, Martin K. Petersen wrote:
> On Mon, 19 Jul 2021 16:11:22 -0700, Bart Van Assche wrote:

> 

> 

> 

> > If param_offset > buff_len then the memcpy() statement in

> > ufshcd_read_desc_param() corrupts memory since it copies

> > 256 + buff_len - param_offset bytes into a buffer with size

> > buff_len.

> > Since param_offset < 256 this results in writing past the bound of

> > the

> > output buffer.

> 

> 

> Applied to 5.14/scsi-fixes, thanks!

> 

> 

> 

> [1/1] scsi: ufs: Fix memory corruption by ufshcd_read_desc_param()

> 

>       https://git.kernel.org/mkp/scsi/c/b1d5de8c6ea2


Hi Martin,
This patch has a problem, we should revert it.

and the correct fix patch is in Bart's another series of patch:
https://patchwork.kernel.org/project/linux-scsi/patch/20210722033439.26550-2-bvanassche@acm.org/

Bean
Martin K. Petersen July 30, 2021, 2:56 a.m. UTC | #5
Bean,

> This patch has a problem, we should revert it.

>

> and the correct fix patch is in Bart's another series of patch:


OK, that explains why b4 was confused. Dropped.

-- 
Martin K. Petersen	Oracle Linux Engineering
diff mbox series

Patch

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 89da2cf2c969..00502ffe9b4a 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -3365,7 +3365,9 @@  int ufshcd_read_desc_param(struct ufs_hba *hba,
 
 	if (is_kmalloc) {
 		/* Make sure we don't copy more data than available */
-		if (param_offset + param_size > buff_len)
+		if (buff_len < param_offset)
+			param_size = 0;
+		else if (param_offset + param_size > buff_len)
 			param_size = buff_len - param_offset;
 		memcpy(param_read_buf, &desc_buf[param_offset], param_size);
 	}