aboutsummaryrefslogtreecommitdiff
path: root/include
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 /include
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 'include')
-rw-r--r--include/printf_buffer.h19
1 files changed, 14 insertions, 5 deletions
diff --git a/include/printf_buffer.h b/include/printf_buffer.h
index 55feebf..4d787e4 100644
--- a/include/printf_buffer.h
+++ b/include/printf_buffer.h
@@ -115,19 +115,28 @@ __printf_buffer_has_failed (struct __printf_buffer *buf)
return buf->mode == __printf_buffer_mode_failed;
}
-/* Initialization of a buffer, using the memory region from [BASE, BASE +LEN)
- as the initial buffer contents. LEN can be zero. */
+/* Initialization of a buffer, using the memory region from [BASE,
+ END) as the initial buffer contents. */
static inline void
-__printf_buffer_init (struct __printf_buffer *buf, char *base, size_t len,
- enum __printf_buffer_mode mode)
+__printf_buffer_init_end (struct __printf_buffer *buf, char *base, char *end,
+ enum __printf_buffer_mode mode)
{
buf->write_base = base;
buf->write_ptr = base;
- buf->write_end = base + len;
+ buf->write_end = end;
buf->written = 0;
buf->mode = mode;
}
+/* Initialization of a buffer, using the memory region from [BASE, BASE +LEN)
+ as the initial buffer contents. LEN can be zero. */
+static inline void
+__printf_buffer_init (struct __printf_buffer *buf, char *base, size_t len,
+ enum __printf_buffer_mode mode)
+{
+ __printf_buffer_init_end (buf, base, base + len, mode);
+}
+
/* Called by printf_buffer_putc for a full buffer. */
void __printf_buffer_putc_1 (struct __printf_buffer *buf, char ch)
attribute_hidden;