aboutsummaryrefslogtreecommitdiff
path: root/libio
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2023-01-25 08:01:00 +0100
committerFlorian Weimer <fweimer@redhat.com>2023-01-25 08:01:00 +0100
commit0d50f477f47ba637b54fb03ac48d769ec4543e8d (patch)
tree598fbe050d8441a6152237d5442d2506ed846bf0 /libio
parent0674613e6652a46063756f162bdef88622b3bdbd (diff)
downloadglibc-0d50f477f47ba637b54fb03ac48d769ec4543e8d.zip
glibc-0d50f477f47ba637b54fb03ac48d769ec4543e8d.tar.gz
glibc-0d50f477f47ba637b54fb03ac48d769ec4543e8d.tar.bz2
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>
Diffstat (limited to 'libio')
-rw-r--r--libio/iovsprintf.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c
index 8d53e40..9a4f59a 100644
--- a/libio/iovsprintf.c
+++ b/libio/iovsprintf.c
@@ -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);