1
0
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:
Florian Weimer
2023-01-25 08:01:00 +01:00
parent 0674613e66
commit 0d50f477f4
4 changed files with 155 additions and 10 deletions

View File

@@ -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);