aboutsummaryrefslogtreecommitdiff
path: root/libio/iovsprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libio/iovsprintf.c')
-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);