Fix integer overflow in psf_log_printf()

https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28441

Credit to OSS-Fuzz.
This commit is contained in:
evpobr 2021-11-03 12:33:24 +05:00
parent f1495b4bcc
commit 404bf9af79
2 changed files with 29 additions and 16 deletions

View File

@ -88,6 +88,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([issue 27366](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=27366)). ([issue 27366](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=27366)).
* Integer overflow in `nms_adpcm_update`(), credit to OSS-Fuzz * Integer overflow in `nms_adpcm_update`(), credit to OSS-Fuzz
([issue 25522](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25522)). ([issue 25522](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=25522)).
* Integer overflow in `psf_log_printf`(), credit to OSS-Fuzz
([issue 28441](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28441)).
* ABI version incompatibility between Autotools and CMake build on Apple * ABI version incompatibility between Autotools and CMake build on Apple
platforms. platforms.

View File

@ -103,8 +103,8 @@ log_putchar (SF_PRIVATE *psf, char ch)
void void
psf_log_printf (SF_PRIVATE *psf, const char *format, ...) psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
{ va_list ap ; { va_list ap ;
uint32_t u ; uint32_t u, tens ;
int d, tens, shift, width, width_specifier, left_align, slen, precision ; int d, shift, width, width_specifier, left_align, slen, precision ;
char c, *strptr, istr [5], lead_char, sign_char ; char c, *strptr, istr [5], lead_char, sign_char ;
va_start (ap, format) ; va_start (ap, format) ;
@ -186,15 +186,19 @@ psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
d = va_arg (ap, int) ; d = va_arg (ap, int) ;
if (d < 0) if (d < 0)
{ d = -d ; { sign_char = '-' ;
sign_char = '-' ;
if (lead_char != '0' && left_align == SF_FALSE) if (lead_char != '0' && left_align == SF_FALSE)
width_specifier -- ; width_specifier -- ;
} ;
u = - ((unsigned) d) ;
}
else
{ u = (unsigned) d ;
}
tens = 1 ; tens = 1 ;
width = 1 ; width = 1 ;
while (d / tens >= 10) while (u / tens >= 10)
{ tens *= 10 ; { tens *= 10 ;
width ++ ; width ++ ;
} ; } ;
@ -224,8 +228,8 @@ psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
log_putchar (psf, lead_char) ; log_putchar (psf, lead_char) ;
while (tens > 0) while (tens > 0)
{ log_putchar (psf, '0' + d / tens) ; { log_putchar (psf, '0' + u / tens) ;
d %= tens ; u %= tens ;
tens /= 10 ; tens /= 10 ;
} ; } ;
@ -234,7 +238,8 @@ psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
break ; break ;
case 'D': /* sf_count_t */ case 'D': /* sf_count_t */
{ sf_count_t D, Tens ; { sf_count_t D ;
uint64_t U, Tens ;
D = va_arg (ap, sf_count_t) ; D = va_arg (ap, sf_count_t) ;
@ -244,13 +249,19 @@ psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
log_putchar (psf, '0') ; log_putchar (psf, '0') ;
break ; break ;
} }
if (D < 0) else
{ log_putchar (psf, '-') ; { if (D < 0)
D = -D ; { log_putchar (psf, '-') ;
} ; U = -((uint64_t) D) ;
}
else
{ U = (uint64_t) D;
}
}
Tens = 1 ; Tens = 1 ;
width = 1 ; width = 1 ;
while (D / Tens >= 10) while (U / Tens >= 10)
{ Tens *= 10 ; { Tens *= 10 ;
width ++ ; width ++ ;
} ; } ;
@ -261,8 +272,8 @@ psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
} ; } ;
while (Tens > 0) while (Tens > 0)
{ log_putchar (psf, '0' + D / Tens) ; { log_putchar (psf, '0' + U / Tens) ;
D %= Tens ; U %= Tens ;
Tens /= 10 ; Tens /= 10 ;
} ; } ;
} ; } ;