mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-23 03:10:05 +00:00
Fix boundary conditions in scanf
Allocate large buffers with realloc. When returning error make sure the stream is unlocked.
This commit is contained in:
parent
e4899e7b9a
commit
3f8cc204fd
@ -1,5 +1,11 @@
|
||||
2011-09-09 Ulrich Drepper <drepper@gmail.com>
|
||||
|
||||
[BZ #13138]
|
||||
* stdio-common/vfscanf.c (ADDW): Allocate large memory block with
|
||||
realloc.
|
||||
(_IO_vfscanf_internal): Remove reteof. Use errout after setting done.
|
||||
Free memory block if necessary.
|
||||
|
||||
[BZ #12847]
|
||||
* libio/genops.c (INTDEF): For string streams the _lock pointer can
|
||||
be NULL. Don't lock in this case.
|
||||
|
2
NEWS
2
NEWS
@ -10,7 +10,7 @@ Version 2.15
|
||||
* The following bugs are resolved with this release:
|
||||
|
||||
9696, 12403, 12847, 12868, 12852, 12874, 12885, 12907, 12922, 12935,
|
||||
13007, 13021, 13068, 13092, 13114, 13118, 13123, 13134, 13150
|
||||
13007, 13021, 13068, 13092, 13114, 13118, 13123, 13134, 13138, 13150
|
||||
|
||||
* New program pldd to list loaded object of a process
|
||||
Implemented by Ulrich Drepper.
|
||||
|
@ -265,16 +265,39 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
CHAR_T *wp = NULL; /* Workspace. */
|
||||
size_t wpmax = 0; /* Maximal size of workspace. */
|
||||
size_t wpsize; /* Currently used bytes in workspace. */
|
||||
bool use_malloc = false;
|
||||
#define ADDW(Ch) \
|
||||
do \
|
||||
{ \
|
||||
if (wpsize == wpmax) \
|
||||
if (__builtin_expect (wpsize == wpmax, 0)) \
|
||||
{ \
|
||||
CHAR_T *old = wp; \
|
||||
wpmax = (UCHAR_MAX + 1 > 2 * wpmax ? UCHAR_MAX + 1 : 2 * wpmax); \
|
||||
wp = (CHAR_T *) alloca (wpmax * sizeof (CHAR_T)); \
|
||||
if (old != NULL) \
|
||||
MEMCPY (wp, old, wpsize); \
|
||||
size_t newsize = (UCHAR_MAX + 1 > 2 * wpmax \
|
||||
? UCHAR_MAX + 1 : 2 * wpmax); \
|
||||
if (use_malloc || __libc_use_alloca (newsize)) \
|
||||
{ \
|
||||
wp = realloc (use_malloc ? wp : NULL, newsize); \
|
||||
if (wp == NULL) \
|
||||
{ \
|
||||
if (use_malloc) \
|
||||
free (old); \
|
||||
done = EOF; \
|
||||
goto errout; \
|
||||
} \
|
||||
if (! use_malloc) \
|
||||
MEMCPY (wp, old, wpsize); \
|
||||
wpmax = newsize; \
|
||||
use_malloc = true; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
size_t s = wpmax * sizeof (CHAR_T); \
|
||||
wp = (CHAR_T *) extend_alloca (wp, s, \
|
||||
newsize * sizeof (CHAR_T)); \
|
||||
wpmax = s / sizeof (CHAR_T); \
|
||||
if (old != NULL) \
|
||||
MEMCPY (wp, old, wpsize); \
|
||||
} \
|
||||
} \
|
||||
wp[wpsize++] = (Ch); \
|
||||
} \
|
||||
@ -670,7 +693,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
if (Str != NULL) \
|
||||
add_ptr_to_free (strptr); \
|
||||
else if (flags & POSIX_MALLOC) \
|
||||
goto reteof; \
|
||||
{ \
|
||||
done = EOF; \
|
||||
goto errout; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
Str = ARG (Type *); \
|
||||
@ -711,8 +737,11 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
newstr = (char *) realloc (*strptr,
|
||||
strleng + MB_CUR_MAX);
|
||||
if (newstr == NULL)
|
||||
/* c can't have `a' flag, only `m'. */
|
||||
goto reteof;
|
||||
{
|
||||
/* c can't have `a' flag, only `m'. */
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
else
|
||||
{
|
||||
*strptr = newstr;
|
||||
@ -758,8 +787,11 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
effort. */
|
||||
str = (char *) realloc (*strptr, strsize + 1);
|
||||
if (str == NULL)
|
||||
/* c can't have `a' flag, only `m'. */
|
||||
goto reteof;
|
||||
{
|
||||
/* c can't have `a' flag, only `m'. */
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
else
|
||||
{
|
||||
*strptr = (char *) str;
|
||||
@ -828,8 +860,12 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
(strsize + 1)
|
||||
* sizeof (wchar_t));
|
||||
if (wstr == NULL)
|
||||
/* C or lc can't have `a' flag, only `m' flag. */
|
||||
goto reteof;
|
||||
{
|
||||
/* C or lc can't have `a' flag, only `m'
|
||||
flag. */
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
else
|
||||
{
|
||||
*strptr = (char *) wstr;
|
||||
@ -879,8 +915,11 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
((strsize + 1)
|
||||
* sizeof (wchar_t)));
|
||||
if (wstr == NULL)
|
||||
/* C or lc can't have `a' flag, only `m' flag. */
|
||||
goto reteof;
|
||||
{
|
||||
/* C or lc can't have `a' flag, only `m' flag. */
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
else
|
||||
{
|
||||
*strptr = (char *) wstr;
|
||||
@ -992,7 +1031,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
if (newstr == NULL)
|
||||
{
|
||||
if (flags & POSIX_MALLOC)
|
||||
goto reteof;
|
||||
{
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
/* We lose. Oh well. Terminate the
|
||||
string and stop converting,
|
||||
so at least we don't skip any input. */
|
||||
@ -1042,7 +1084,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
if (str == NULL)
|
||||
{
|
||||
if (flags & POSIX_MALLOC)
|
||||
goto reteof;
|
||||
{
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
/* We lose. Oh well. Terminate the
|
||||
string and stop converting,
|
||||
so at least we don't skip any input. */
|
||||
@ -1088,7 +1133,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
if (newstr == NULL)
|
||||
{
|
||||
if (flags & POSIX_MALLOC)
|
||||
goto reteof;
|
||||
{
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
/* We lose. Oh well. Terminate the string
|
||||
and stop converting, so at least we don't
|
||||
skip any input. */
|
||||
@ -1170,7 +1218,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
if (wstr == NULL)
|
||||
{
|
||||
if (flags & POSIX_MALLOC)
|
||||
goto reteof;
|
||||
{
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
/* We lose. Oh well. Terminate the string
|
||||
and stop converting, so at least we don't
|
||||
skip any input. */
|
||||
@ -1242,7 +1293,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
if (wstr == NULL)
|
||||
{
|
||||
if (flags & POSIX_MALLOC)
|
||||
goto reteof;
|
||||
{
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
/* We lose. Oh well. Terminate the
|
||||
string and stop converting, so at
|
||||
least we don't skip any input. */
|
||||
@ -2433,7 +2487,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
if (wstr == NULL)
|
||||
{
|
||||
if (flags & POSIX_MALLOC)
|
||||
goto reteof;
|
||||
{
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
/* We lose. Oh well. Terminate the string
|
||||
and stop converting, so at least we don't
|
||||
skip any input. */
|
||||
@ -2515,7 +2572,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
if (wstr == NULL)
|
||||
{
|
||||
if (flags & POSIX_MALLOC)
|
||||
goto reteof;
|
||||
{
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
/* We lose. Oh well. Terminate the
|
||||
string and stop converting,
|
||||
so at least we don't skip any input. */
|
||||
@ -2657,7 +2717,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
if (newstr == NULL)
|
||||
{
|
||||
if (flags & POSIX_MALLOC)
|
||||
goto reteof;
|
||||
{
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
/* We lose. Oh well. Terminate the string
|
||||
and stop converting, so at least we don't
|
||||
skip any input. */
|
||||
@ -2722,7 +2785,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
goto allocagain;
|
||||
}
|
||||
if (flags & POSIX_MALLOC)
|
||||
goto reteof;
|
||||
{
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
/* We lose. Oh well. Terminate the
|
||||
string and stop converting,
|
||||
so at least we don't skip any input. */
|
||||
@ -2765,7 +2831,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
if (newstr == NULL)
|
||||
{
|
||||
if (flags & POSIX_MALLOC)
|
||||
goto reteof;
|
||||
{
|
||||
done = EOF;
|
||||
goto errout;
|
||||
}
|
||||
/* We lose. Oh well. Terminate the string
|
||||
and stop converting, so at least we don't
|
||||
skip any input. */
|
||||
@ -2828,12 +2897,14 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
/* Unlock stream. */
|
||||
UNLOCK_STREAM (s);
|
||||
|
||||
if (use_malloc)
|
||||
free (wp);
|
||||
|
||||
if (errp != NULL)
|
||||
*errp |= errval;
|
||||
|
||||
if (done == EOF)
|
||||
if (__builtin_expect (done == EOF, 0))
|
||||
{
|
||||
reteof:
|
||||
if (__builtin_expect (ptrs_to_free != NULL, 0))
|
||||
{
|
||||
struct ptrs_to_free *p = ptrs_to_free;
|
||||
@ -2848,7 +2919,6 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
ptrs_to_free = p;
|
||||
}
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
else if (__builtin_expect (strptr != NULL, 0))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user