From a8d02c5ca706384c53c941b3041c326c62a6f09e Mon Sep 17 00:00:00 2001 From: Eugene Syromiatnikov Date: Tue, 5 Aug 2025 14:51:22 +0200 Subject: [PATCH] crypto/bio/bio_print.c: avoid integer overflow when reading width/precision MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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) --- crypto/bio/bio_print.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) 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); -- 2.47.3