[PATCH 1/2] stdio-common: Use reallocarray for wide strings in vfscanf
Florian Weimer <[email protected]>
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Message-ID | <c0875b265621beda69b08080e3a9ed1f80c32894.1786961109.git.fweimer@redhat.com> |
This avoids theoretical integer overflow issues on 32-bit
architectures. The overflow is not reachable since glibc 2.30
because doubling reaches a size larger than PTRDIFF_MAX, at which
point realloc fails due to commit 9bf8e29ca136094f73f6 ("malloc:
make malloc fail with requests larger than PTRDIFF_MAX (BZ#23741)").
The non-doubling path is used instead. Eventually, the size
increments also pass PTRDIFF_MAX, so the fallback realloc fails, too.
This means that in current glibc, there is no crash.
---
stdio-common/vfscanf-internal.c | 77 +++++++++++++++++----------------
1 file changed, 39 insertions(+), 38 deletions(-)
diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c
index 5f548f709f..e2e08c0eab 100644
--- a/stdio-common/vfscanf-internal.c
+++ b/stdio-common/vfscanf-internal.c
@@ -944,14 +944,15 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
size_t newsize
= strsize + (strsize >= width ? width : strsize);
/* Enlarge the buffer. */
- wstr = (wchar_t *) realloc (*strptr,
- newsize * sizeof (wchar_t));
+ wstr = (wchar_t *)
+ __libc_reallocarray (*strptr, newsize,
+ sizeof (wchar_t));
if (wstr == NULL)
{
/* Can't allocate that much. Last-ditch effort. */
- wstr = (wchar_t *) realloc (*strptr,
- (strsize + 1)
- * sizeof (wchar_t));
+ wstr = (wchar_t *)
+ __libc_reallocarray (*strptr, strsize + 1,
+ sizeof (wchar_t));
if (wstr == NULL)
{
/* C or lc can't have `a' flag, only `m'
@@ -999,14 +1000,14 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
size_t newsize
= strsize + (strsize >= width ? width : strsize);
/* Enlarge the buffer. */
- wstr = (wchar_t *) realloc (*strptr,
- newsize * sizeof (wchar_t));
+ wstr = (wchar_t *) __libc_reallocarray (*strptr, newsize,
+ sizeof (wchar_t));
if (wstr == NULL)
{
/* Can't allocate that much. Last-ditch effort. */
- wstr = (wchar_t *) realloc (*strptr,
- ((strsize + 1)
- * sizeof (wchar_t)));
+ wstr = (wchar_t *)
+ __libc_reallocarray (*strptr, strsize + 1,
+ sizeof (wchar_t));
if (wstr == NULL)
{
/* C or lc can't have `a' flag, only `m' flag. */
@@ -1066,10 +1067,9 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
{
if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
{
- wchar_t *cp = (wchar_t *) realloc (*strptr,
- ((wstr
- - (wchar_t *) *strptr)
- * sizeof (wchar_t)));
+ wchar_t *cp = (wchar_t *)
+ __libc_reallocarray (*strptr, wstr - (wchar_t *) *strptr,
+ sizeof (wchar_t));
if (cp != NULL)
*strptr = (char *) cp;
}
@@ -1305,15 +1305,15 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
/* Enlarge the buffer. */
size_t newsize = grow_to_fit (strsize, width);
- wstr = (wchar_t *) realloc (
- *strptr, newsize * sizeof (wchar_t));
+ wstr = (wchar_t *) __libc_reallocarray
+ (*strptr, newsize, sizeof (wchar_t));
if (wstr == NULL)
{
/* Can't allocate that much. Last-ditch
effort. */
- wstr = (wchar_t *) realloc (*strptr,
- (strsize + 1)
- * sizeof (wchar_t));
+ wstr = (wchar_t *)
+ __libc_reallocarray (*strptr, strsize + 1,
+ sizeof (wchar_t));
if (wstr == NULL)
{
if (flags & POSIX_MALLOC)
@@ -1382,14 +1382,15 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
/* Enlarge the buffer. */
size_t newsize = grow_to_fit (strsize, width);
- wstr = (wchar_t *) realloc (*strptr,
- newsize * sizeof (wchar_t));
+ wstr = (wchar_t *)
+ __libc_reallocarray (*strptr, newsize,
+ sizeof (wchar_t));
if (wstr == NULL)
{
/* Can't allocate that much. Last-ditch effort. */
- wstr = (wchar_t *) realloc (*strptr,
- ((strsize + 1)
- * sizeof (wchar_t)));
+ wstr = (wchar_t *)
+ __libc_reallocarray (*strptr, strsize + 1,
+ sizeof (wchar_t));
if (wstr == NULL)
{
if (flags & POSIX_MALLOC)
@@ -1430,10 +1431,9 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr,
if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
{
- wchar_t *cp = (wchar_t *) realloc (*strptr,
- ((wstr
- - (wchar_t *) *strptr)
- * sizeof (wchar_t)));
+ wchar_t *cp = (wchar_t *)
+ __libc_reallocarray (*strptr, wstr - (wchar_t *) *strptr,
+ sizeof (wchar_t));
if (cp != NULL)
*strptr = (char *) cp;
}
@@ -2800,15 +2800,15 @@ digits_extended_fail:
/* Enlarge the buffer. */
size_t newsize = grow_to_fit (strsize, width);
- wstr = (wchar_t *) realloc (
- *strptr, newsize * sizeof (wchar_t));
+ wstr = (wchar_t *) __libc_reallocarray
+ (*strptr, newsize, sizeof (wchar_t));
if (wstr == NULL)
{
/* Can't allocate that much. Last-ditch
effort. */
wstr = (wchar_t *)
- realloc (*strptr, (strsize + 1)
- * sizeof (wchar_t));
+ __libc_reallocarray (*strptr, strsize + 1,
+ sizeof (wchar_t));
if (wstr == NULL)
{
if (flags & POSIX_MALLOC)
@@ -2886,15 +2886,15 @@ digits_extended_fail:
/* Enlarge the buffer. */
size_t newsize = grow_to_fit (strsize, width);
- wstr = (wchar_t *) realloc (
- *strptr, newsize * sizeof (wchar_t));
+ wstr = (wchar_t *) __libc_reallocarray
+ (*strptr, newsize, sizeof (wchar_t));
if (wstr == NULL)
{
/* Can't allocate that much. Last-ditch
effort. */
wstr = (wchar_t *)
- realloc (*strptr, ((strsize + 1)
- * sizeof (wchar_t)));
+ __libc_reallocarray (*strptr, strsize + 1,
+ sizeof (wchar_t));
if (wstr == NULL)
{
if (flags & POSIX_MALLOC)
@@ -2949,8 +2949,9 @@ digits_extended_fail:
&& wstr - (wchar_t *) *strptr != strsize)
{
wchar_t *cp = (wchar_t *)
- realloc (*strptr, ((wstr - (wchar_t *) *strptr)
- * sizeof (wchar_t)));
+ __libc_reallocarray (*strptr,
+ wstr - (wchar_t *) *strptr,
+ sizeof (wchar_t));
if (cp != NULL)
*strptr = (char *) cp;
}
base-commit: 6144ef08960e1db191db2054abef02d361042018
--
2.55.0