mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-05 19:35:52 +03:00
libio: asprintf should write NULL upon failure
This was suggested most recently by Solar Designer, noting that code replacing vsprintf with vasprintf in a security fix was subtly wrong: Re: GStreamer Security Advisory 2024-0003: Orc compiler stack-based buffer overflow <https://www.openwall.com/lists/oss-security/2024/07/26/2> Previous libc-alpha discussions: I: [PATCH] asprintf error handling fix <https://inbox.sourceware.org/libc-alpha/20011205185828.GA8376@ldv.office.alt-linux.org/> asprintf() issue <https://inbox.sourceware.org/libc-alpha/CANSoFxt-cdc-+C4u-rTENMtY4X9RpRSuv+axDswSPxbDgag8_Q@mail.gmail.com/> I don't think we need a compatibility symbol for this. As the GStreamer example shows, this change is much more likely to fix bugs than cause compatibility issues. Suggested-by: Dmitry V. Levin <ldv@altlinux.org> Suggested-by: Archie Cobbs <archie.cobbs@gmail.com> Suggested-by: Solar Designer <solar@openwall.com> Reviewed-by: Sam James <sam@gentoo.org>
This commit is contained in:
@@ -92,7 +92,7 @@ __printf_buffer_flush_asprintf (struct __printf_buffer_asprintf *buf)
|
||||
|
||||
|
||||
int
|
||||
__vasprintf_internal (char **result_ptr, const char *format, va_list args,
|
||||
__vasprintf_internal (char **result, const char *format, va_list args,
|
||||
unsigned int mode_flags)
|
||||
{
|
||||
struct __printf_buffer_asprintf buf;
|
||||
@@ -105,23 +105,23 @@ __vasprintf_internal (char **result_ptr, const char *format, va_list args,
|
||||
{
|
||||
if (buf.base.write_base != buf.direct)
|
||||
free (buf.base.write_base);
|
||||
*result = NULL;
|
||||
return done;
|
||||
}
|
||||
|
||||
/* Transfer to the final buffer. */
|
||||
char *result;
|
||||
size_t size = buf.base.write_ptr - buf.base.write_base;
|
||||
if (buf.base.write_base == buf.direct)
|
||||
{
|
||||
result = malloc (size + 1);
|
||||
if (result == NULL)
|
||||
*result = malloc (size + 1);
|
||||
if (*result == NULL)
|
||||
return -1;
|
||||
memcpy (result, buf.direct, size);
|
||||
memcpy (*result, buf.direct, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = realloc (buf.base.write_base, size + 1);
|
||||
if (result == NULL)
|
||||
*result = realloc (buf.base.write_base, size + 1);
|
||||
if (*result == NULL)
|
||||
{
|
||||
free (buf.base.write_base);
|
||||
return -1;
|
||||
@@ -129,8 +129,7 @@ __vasprintf_internal (char **result_ptr, const char *format, va_list args,
|
||||
}
|
||||
|
||||
/* Add NUL termination. */
|
||||
result[size] = '\0';
|
||||
*result_ptr = result;
|
||||
(*result)[size] = '\0';
|
||||
|
||||
return done;
|
||||
}
|
||||
|
Reference in New Issue
Block a user