mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-08 17:42:12 +03:00
stdio-common: Handle -1 buffer size in __sprintf_chk & co (bug 30039)
This shows up as an assertion failure when sprintf is called with a specifier like "%.8g" and libquadmath is linked in: Fatal glibc error: printf_buffer_as_file.c:31 (__printf_buffer_as_file_commit): assertion failed: file->stream._IO_write_ptr <= file->next->write_end Fix this by detecting pointer wraparound in __vsprintf_internal and saturate the addition to the end of the address space instead. Reviewed-by: Carlos O'Donell <carlos@redhat.com> Tested-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
@@ -45,14 +45,19 @@ __vsprintf_internal (char *string, size_t maxlen,
|
||||
if ((mode_flags & PRINTF_CHK) != 0)
|
||||
{
|
||||
string[0] = '\0';
|
||||
__printf_buffer_init (&buf, string, maxlen,
|
||||
/* In some cases, __sprintf_chk is called with an unknown buffer
|
||||
size (the special value -1). Prevent pointer wraparound in
|
||||
this case and saturate to the end of the address space. */
|
||||
uintptr_t end;
|
||||
if (__builtin_add_overflow ((uintptr_t) string, maxlen, &end))
|
||||
end = -1;
|
||||
__printf_buffer_init_end (&buf, string, (char *) end,
|
||||
__printf_buffer_mode_sprintf_chk);
|
||||
}
|
||||
else
|
||||
{
|
||||
__printf_buffer_init (&buf, string, 0, __printf_buffer_mode_sprintf);
|
||||
buf.write_end = (char *) ~(uintptr_t) 0; /* End of address space. */
|
||||
}
|
||||
/* Use end of address space. */
|
||||
__printf_buffer_init_end (&buf, string, (char *) ~(uintptr_t) 0,
|
||||
__printf_buffer_mode_sprintf);
|
||||
|
||||
__printf_buffer (&buf, format, args, mode_flags);
|
||||
|
||||
|
Reference in New Issue
Block a user