On 2/14/23 16:14, Arnd Bergmann wrote: > 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. Yeah. The HW probably always give the same amount of chars with short strings completed by spaces... > >>> + 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 -- Damien Le Moal Western Digital Research