From: Eugene Syromiatnikov Date: Tue, 5 Aug 2025 12:51:22 +0000 (+0200) Subject: crypto/bio/bio_print.c: avoid integer overflow when reading width/precision X-Git-Tag: openssl-3.6.0-alpha1~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a8d02c5ca706384c53c941b3041c326c62a6f09e;p=thirdparty%2Fopenssl.git 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 Reviewed-by: Saša Nedvědický Reviewed-by: Neil Horman (Merged from https://github.com/openssl/openssl/pull/28177) --- diff --git a/crypto/bio/bio_print.c b/crypto/bio/bio_print.c index dc66603aad3..82aecf82acf 100644 --- a/crypto/bio/bio_print.c +++ b/crypto/bio/bio_print.c @@ -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);