|
|
Message-ID: <20260805075215.3508837-1-matthias.goergens@gmail.com>
Date: Wed, 5 Aug 2026 15:52:14 +0800
From: Matthias Goergens <matthias.goergens@...il.com>
To: musl@...ts.openwall.com
Cc: Matthias Goergens <matthias.goergens@...il.com>
Subject: [PATCH 1/2] stdio: avoid field width overflow in scanf
Decimal field widths are accumulated in int. The old expression can
overflow as early as valid width 2147483600 because it adds the digit
character value before subtracting '0'. Larger widths overflow too.
This issue was noted in a 2018 stdio review, but the report described an
INT_MIN case and the reachable positive boundary remained unclear.
Use the existing bounded-parser idiom from printf, with the digit
subtraction grouped before addition. Accept widths through INT_MAX and
reject larger values as an invalid format rather than allowing them to
wrap.
---
src/stdio/vfscanf.c | 4 +++-
src/stdio/vfwscanf.c | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/stdio/vfscanf.c b/src/stdio/vfscanf.c
index b78a374d..07bb3845 100644
--- a/src/stdio/vfscanf.c
+++ b/src/stdio/vfscanf.c
@@ -118,7 +118,9 @@ int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap)
}
for (width=0; isdigit(*p); p++) {
- width = 10*width + *p - '0';
+ if (width > INT_MAX/10U || *p-'0' > INT_MAX-10*width)
+ goto fmt_fail;
+ width = 10*width + (*p-'0');
}
if (*p=='m') {
diff --git a/src/stdio/vfwscanf.c b/src/stdio/vfwscanf.c
index 82f48604..1497aa0d 100644
--- a/src/stdio/vfwscanf.c
+++ b/src/stdio/vfwscanf.c
@@ -141,7 +141,9 @@ int vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
}
for (width=0; iswdigit(*p); p++) {
- width = 10*width + *p - '0';
+ if (width > INT_MAX/10U || *p-'0' > INT_MAX-10*width)
+ goto fmt_fail;
+ width = 10*width + (*p-'0');
}
if (*p=='m') {
--
2.55.0
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.