* [PATCH] vfscanf: Avoid multiple reads of multi-byte character width
@ 2016-09-02 13:19 Florian Weimer
2016-09-02 13:56 ` Andreas Schwab
0 siblings, 1 reply; 3+ messages in thread
From: Florian Weimer @ 2016-09-02 13:19 UTC (permalink / raw)
To: libc-alpha
This avoids a race condition if the process-global locale is changed
while vfscanf is running. MB_LEN_MAX is always larger than MB_CUR_MAX,
so we might realloc earlier than necessary (but even MB_CUR_MAX could
be larger than the minimum required space).
The existing length was a bit questionable because str + MB_LEN_MAX
might point past the end of the buffer.
2016-09-02 Florian Weimer <fweimer@redhat.com>
* stdio-common/vfscanf.c (_IO_vfwscanf): Use MB_LEN_MAX instead of
MB_CUR_MAX to avoid race condition. Avoid pointer arithmetic
outside of allocated array.
diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
index 8cd5955..2b7093e 100644
--- a/stdio-common/vfscanf.c
+++ b/stdio-common/vfscanf.c
@@ -757,7 +757,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
size_t n;
if (!(flags & SUPPRESS) && (flags & POSIX_MALLOC)
- && str + MB_CUR_MAX >= *strptr + strsize)
+ && MB_LEN_MAX >= *strptr + strsize - str)
{
/* We have to enlarge the buffer if the `m' flag
was given. */
@@ -769,7 +769,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
{
/* Can't allocate that much. Last-ditch effort. */
newstr = (char *) realloc (*strptr,
- strleng + MB_CUR_MAX);
+ strleng + MB_LEN_MAX);
if (newstr == NULL)
{
/* c can't have `a' flag, only `m'. */
@@ -780,7 +780,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
{
*strptr = newstr;
str = newstr + strleng;
- strsize = strleng + MB_CUR_MAX;
+ strsize = strleng + MB_LEN_MAX;
}
}
else
@@ -1048,7 +1048,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
size_t n;
if (!(flags & SUPPRESS) && (flags & MALLOC)
- && str + MB_CUR_MAX >= *strptr + strsize)
+ && MB_LEN_MAX >= *strptr + strsize - str)
{
/* We have to enlarge the buffer if the `a' or `m'
flag was given. */
@@ -1061,7 +1061,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
/* Can't allocate that much. Last-ditch
effort. */
newstr = (char *) realloc (*strptr,
- strleng + MB_CUR_MAX);
+ strleng + MB_LEN_MAX);
if (newstr == NULL)
{
if (flags & POSIX_MALLOC)
@@ -1081,7 +1081,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
{
*strptr = newstr;
str = newstr + strleng;
- strsize = strleng + MB_CUR_MAX;
+ strsize = strleng + MB_LEN_MAX;
}
}
else
@@ -1097,7 +1097,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
if (__glibc_unlikely (n == (size_t) -1))
encode_error ();
- assert (n <= MB_CUR_MAX);
+ assert (n <= MB_LEN_MAX);
str += n;
}
#else
@@ -2675,7 +2675,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
/* Possibly correct character, just not enough
input. */
++cnt;
- assert (cnt < MB_CUR_MAX);
+ assert (cnt < MB_LEN_MAX);
continue;
}
cnt = 0;
@@ -2827,7 +2827,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
if (!(flags & SUPPRESS))
{
if ((flags & MALLOC)
- && str + MB_CUR_MAX >= *strptr + strsize)
+ && MB_LEN_MAX >= *strptr + strsize - str)
{
/* Enlarge the buffer. */
size_t strleng = str - *strptr;
@@ -2839,7 +2839,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
/* Can't allocate that much. Last-ditch
effort. */
newstr = (char *) realloc (*strptr,
- strleng + MB_CUR_MAX);
+ strleng + MB_LEN_MAX);
if (newstr == NULL)
{
if (flags & POSIX_MALLOC)
@@ -2859,7 +2859,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
{
*strptr = newstr;
str = newstr + strleng;
- strsize = strleng + MB_CUR_MAX;
+ strsize = strleng + MB_LEN_MAX;
}
}
else
@@ -2875,7 +2875,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
if (__glibc_unlikely (n == (size_t) -1))
encode_error ();
- assert (n <= MB_CUR_MAX);
+ assert (n <= MB_LEN_MAX);
str += n;
}
while (--width > 0 && inchar () != WEOF);
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] vfscanf: Avoid multiple reads of multi-byte character width
2016-09-02 13:19 [PATCH] vfscanf: Avoid multiple reads of multi-byte character width Florian Weimer
@ 2016-09-02 13:56 ` Andreas Schwab
2016-09-02 14:15 ` Florian Weimer
0 siblings, 1 reply; 3+ messages in thread
From: Andreas Schwab @ 2016-09-02 13:56 UTC (permalink / raw)
To: Florian Weimer; +Cc: libc-alpha
On Sep 02 2016, fweimer@redhat.com (Florian Weimer) wrote:
> diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
> index 8cd5955..2b7093e 100644
> --- a/stdio-common/vfscanf.c
> +++ b/stdio-common/vfscanf.c
> @@ -757,7 +757,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
> size_t n;
>
> if (!(flags & SUPPRESS) && (flags & POSIX_MALLOC)
> - && str + MB_CUR_MAX >= *strptr + strsize)
> + && MB_LEN_MAX >= *strptr + strsize - str)
Please reorder the condition to put the constant part on the right hand
side (also below).
Ok with that change.
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] vfscanf: Avoid multiple reads of multi-byte character width
2016-09-02 13:56 ` Andreas Schwab
@ 2016-09-02 14:15 ` Florian Weimer
0 siblings, 0 replies; 3+ messages in thread
From: Florian Weimer @ 2016-09-02 14:15 UTC (permalink / raw)
To: Andreas Schwab; +Cc: libc-alpha
On 09/02/2016 03:56 PM, Andreas Schwab wrote:
> On Sep 02 2016, fweimer@redhat.com (Florian Weimer) wrote:
>
>> diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
>> index 8cd5955..2b7093e 100644
>> --- a/stdio-common/vfscanf.c
>> +++ b/stdio-common/vfscanf.c
>> @@ -757,7 +757,7 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
>> size_t n;
>>
>> if (!(flags & SUPPRESS) && (flags & POSIX_MALLOC)
>> - && str + MB_CUR_MAX >= *strptr + strsize)
>> + && MB_LEN_MAX >= *strptr + strsize - str)
>
> Please reorder the condition to put the constant part on the right hand
> side (also below).
Thanks, committed with that change.
Florian
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-09-02 14:15 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-02 13:19 [PATCH] vfscanf: Avoid multiple reads of multi-byte character width Florian Weimer
2016-09-02 13:56 ` Andreas Schwab
2016-09-02 14:15 ` Florian Weimer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).