Re: [PATCH] scsi: ipr: work around fortify-string warning

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Feb 14, 2023, at 04:59, Damien Le Moal wrote:
> On 2/13/23 19:10, Arnd Bergmann wrote:
>> From: Arnd Bergmann <arnd@xxxxxxxx>

>>   **/
>> -static int strip_and_pad_whitespace(int i, char *buf)
>> +static void strip_whitespace(int i, char *buf)
>>  {
>>  	while (i && buf[i] == ' ')
>>  		i--;
>> -	buf[i+1] = ' ';
>> -	buf[i+2] = '\0';
>> -	return i + 2;
>> +	buf[i+1] = '\0';
>
> If i is now the size of the buffer, this is a buffer overflow, no ? And
> the initial loop should start at "i - 1" I think...

Right, I definitely have the wrong length here.

>>  }
>>  
>>  /**
>> @@ -1547,19 +1543,21 @@ static int strip_and_pad_whitespace(int i, char *buf)
>>  static void ipr_log_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb,
>>  				struct ipr_vpd *vpd)
>>  {
>> -	char buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN + IPR_SERIAL_NUM_LEN + 3];
>> -	int i = 0;
>> +	char vendor_id[IPR_VENDOR_ID_LEN + 1];
>
> ...but the size is in fact "i + 1"... So in strip_whitespace(), i is the
> index of the last possible character in the string, and given that the
> string may be much shorter, that function may not actually strip
> whitespaces after the string...

I think aside from the off-by-one bug I introduced, this is not
a (new) problem as the old code already assumed that the input
is padded with spaces rather than nul-terminated.

>> +	char product_id[IPR_PROD_ID_LEN + 1];
>> +	char sn[IPR_SERIAL_NUM_LEN + 1];
>>  
>> -	memcpy(buffer, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN);
>> -	i = strip_and_pad_whitespace(IPR_VENDOR_ID_LEN - 1, buffer);
>> +	memcpy(vendor_id, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN);
>> +	strip_whitespace(IPR_VENDOR_ID_LEN, vendor_id);
>
> So this call should really be:
>
> 	strip_whitespace(strlen(vendor_id) - 1, vendor_id);
>
> Which means that this helper can be turned into:
>
> static void strip_whitespace(char *buf)
> {
> 	int i = strlen(buf) - 1;
>
> 	while (i > 0 && buf[i] == ' ')
> 		i--;
> 	buf[i+1] = '\0';
> }
>
> Unless I am missing something :)

The strlen() here requires the input to be a properly terminated string,
so this would at least require adding a \0.

Also, if the input is a short nul-terminated string instead of
a space padded array, we probably don't need to strip the trailing
whitespace, or at least the original version didn't either.

Let me try to respin my patch with just the off-by-one error
fixed but otherwise keeping the output of ipr_log_vpd_compact()
unchanged.

      Arnd



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux