[Stgt-devel] [PATCH spc/mmc 4/4] RESEND modesense memory corruption bug

FUJITA Tomonori fujita.tomonori
Tue May 6 16:43:48 CEST 2008


On Tue, 6 May 2008 16:50:40 +1000
"ronnie sahlberg" <ronniesahlberg at gmail.com> wrote:

> >From 37275d5cfafc87a165824cbf9722ea742a770403 Mon Sep 17 00:00:00 2001
> From: Ronnie Sahlberg <ronniesahlberg at gmail.com>
> Date: Tue, 6 May 2008 16:37:07 +1000
> Subject: [PATCH] Fix a memory corruption bug in build_mode_page
> 
> If an application is providing a small allocation size when asking for a large
> mode page hte memcpy() in build_mode_page can cause memory to be overwritten
> and cause a crash.
> 
> Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
> ---
>  usr/spc.c |   63 ++++++++++++++++++++++++++++++++++--------------------------
>  1 files changed, 36 insertions(+), 27 deletions(-)

Thanks a lot,


> diff --git a/usr/spc.c b/usr/spc.c
> index e3e4d98..35de2e1 100644
> --- a/usr/spc.c
> +++ b/usr/spc.c
> @@ -335,22 +335,28 @@ int spc_test_unit(int host_no, struct scsi_cmd *cmd)
>   *
>   * Returns number of bytes copied.
>   */
> -static int build_mode_page(uint8_t *data, struct mode_pg *pg, int update)
> +static uint8_t *build_mode_page(uint8_t *data, uint8_t *p, int alloc_len,
> +struct mode_pg *pg)
>  {
> -	uint8_t *p;
> -	int len;
> +	int i;
> +
> +	if (alloc_len > (p-data))
> +		*p = pg->pcode;
> +	p++;
> +
> +
> +	if (alloc_len > (p-data))
> +		*p = pg->pcode_size;
> +	p++;
> +
> 
> -	len = pg->pcode_size;
> -	if (update) {
> -		data[0] = pg->pcode;
> -		data[1] = len;
> +	for (i = 0; i < pg->pcode_size; i++) {
> +		if (alloc_len > (p-data))
> +			*p = pg->mode_data[i];
> +		p++;
>  	}
> -	p = &data[2];
> -	len += 2;
> -	if (update)
> -		memcpy(p, pg->mode_data, pg->pcode_size);
> 
> -	return len;
> +	return p;
>  }
> 
>  /**
> @@ -362,12 +368,13 @@ static int build_mode_page(uint8_t *data, struct
> mode_pg *pg, int update)
>   */
>  int spc_mode_sense(int host_no, struct scsi_cmd *cmd)
>  {
> -	int len = 0;
>  	uint8_t *data = NULL, *scb, mode6, dbd, pcode, subpcode;
> +	uint8_t *p;
>  	uint16_t alloc_len;
>  	unsigned char key = ILLEGAL_REQUEST;
>  	uint16_t asc = ASC_INVALID_FIELD_IN_CDB;
>  	struct mode_pg *pg;
> +	int i;
> 
>  	scb = cmd->scb;
>  	mode6 = (scb[0] == 0x1a);
> @@ -383,10 +390,10 @@ int spc_mode_sense(int host_no, struct scsi_cmd *cmd)
> 
>  	if (mode6) {
>  		alloc_len = scb[4];
> -		len = 4;
> +		p = &data[4];
>  	} else {
>  		alloc_len = (scb[7] << 8) + scb[8];
> -		len = 8;
> +		p = &data[8];
>  	}
>  	if (scsi_get_in_length(cmd) < alloc_len)

We still have the same problem here? If a buggy (or malicious)
initiator sends a bogus cdb, alloc_len can be larger than what we
actually allocated.

I'll fix this bug later.



More information about the stgt mailing list