crypto/bio/bio_print.c: avoid integer overflow when reading width/precision

Both width and precision are "decimal digit strings" of unspecified size,
but we can realistically cap it at INT_MAX.

Signed-off-by: Eugene Syromiatnikov <esyr@openssl.org>

Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28177)
This commit is contained in:
Eugene Syromiatnikov 2025-08-05 14:51:22 +02:00 committed by Neil Horman
parent 7777db81f8
commit a8d02c5ca7
1 changed files with 20 additions and 4 deletions

View File

@ -158,9 +158,17 @@ _dopr(char **sbuffer,
break;
}
break;
case DP_S_MIN:
case DP_S_MIN: /* width */
if (ossl_isdigit(ch)) {
min = 10 * min + char_to_int(ch);
/*
* Most implementations cap the possible explicitly specified
* width by (INT_MAX / 10) * 10 - 1 or so (the standard gives
* no clear limit on this), we can do the same.
*/
if (min < INT_MAX / 10)
min = 10 * min + char_to_int(ch);
else
goto out;
ch = *format++;
} else if (ch == '*') {
min = va_arg(args, int);
@ -180,11 +188,19 @@ _dopr(char **sbuffer,
} else
state = DP_S_MOD;
break;
case DP_S_MAX:
case DP_S_MAX: /* precision */
if (ossl_isdigit(ch)) {
if (max < 0)
max = 0;
max = 10 * max + char_to_int(ch);
/*
* Most implementations cap the possible explicitly specified
* width by (INT_MAX / 10) * 10 - 1 or so (the standard gives
* no clear limit on this), we can do the same.
*/
if (max < INT_MAX / 10)
max = 10 * max + char_to_int(ch);
else
goto out;
ch = *format++;
} else if (ch == '*') {
max = va_arg(args, int);