From 1d21eb187fdd4fc078ee45f5fcc854d5ca480da6 Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Tue, 2 Sep 2025 12:25:19 +0200 Subject: [PATCH] libio: Upon asprintf failure set the string pointer to NULL (RHEL-72245) Resolves: RHEL-72245 --- glibc-RHEL-72245.patch | 151 +++++++++++++++++++++++++++++++++++++++++ glibc.spec | 6 +- 2 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-72245.patch diff --git a/glibc-RHEL-72245.patch b/glibc-RHEL-72245.patch new file mode 100644 index 0000000..11dedea --- /dev/null +++ b/glibc-RHEL-72245.patch @@ -0,0 +1,151 @@ +commit cb4692ce1edd5a81c2521de49dfef6125141d1c7 +Author: Florian Weimer +Date: Fri Dec 27 09:17:41 2024 +0100 + + 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 + + + Previous libc-alpha discussions: + + I: [PATCH] asprintf error handling fix + + + asprintf() issue + + + 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 + Suggested-by: Archie Cobbs + Suggested-by: Solar Designer + Reviewed-by: Sam James + +Conflicts: + libio/Makefile + (Test differences) + libio/vasprintf.c + (Adjust for missing change downstream: + "libio: Convert __vasprintf_internal to buffers") + +diff --git a/libio/Makefile b/libio/Makefile +index 1d2a7fd8ba1d06c7..9751a6f82ea80bdc 100644 +--- a/libio/Makefile ++++ b/libio/Makefile +@@ -69,6 +69,7 @@ tests = \ + bug-wmemstream1 \ + bug-wsetpos \ + test-fmemopen \ ++ tst-asprintf-null \ + tst-atime \ + tst-bz22415 \ + tst-bz24051 \ +diff --git a/libio/tst-asprintf-null.c b/libio/tst-asprintf-null.c +new file mode 100644 +index 0000000000000000..1eebeb200f9d41e6 +--- /dev/null ++++ b/libio/tst-asprintf-null.c +@@ -0,0 +1,51 @@ ++/* Test that asprintf sets the buffer pointer to NULL on failure. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ static const char sentinel[] = "sentinel"; ++ char *buf = (char *) sentinel; ++ { ++ /* Avoid -Wformat-overflow warning. */ ++ const char *volatile format = "%2000000000d %2000000000d"; ++ TEST_COMPARE (asprintf (&buf, format, 1, 2), -1); ++ } ++ if (errno != ENOMEM) ++ TEST_COMPARE (errno, EOVERFLOW); ++ TEST_VERIFY (buf == NULL); ++ ++ /* Force ENOMEM in the test below. */ ++ struct rlimit rl; ++ TEST_COMPARE (getrlimit (RLIMIT_AS, &rl), 0); ++ rl.rlim_cur = 10 * 1024 * 1024; ++ TEST_COMPARE (setrlimit (RLIMIT_AS, &rl), 0); ++ ++ buf = (char *) sentinel; ++ TEST_COMPARE (asprintf (&buf, "%20000000d", 1), -1); ++ TEST_COMPARE (errno, ENOMEM); ++ TEST_VERIFY (buf == NULL); ++ return 0; ++} ++ ++#include +diff --git a/libio/vasprintf.c b/libio/vasprintf.c +index c9a09c11c8ca51db..c7d1d933a3a00b4e 100644 +--- a/libio/vasprintf.c ++++ b/libio/vasprintf.c +@@ -44,7 +44,10 @@ __vasprintf_internal (char **result_ptr, const char *format, va_list args, + we know we will never seek on the stream. */ + string = (char *) malloc (init_string_size); + if (string == NULL) +- return -1; ++ { ++ *result_ptr = NULL; ++ return -1; ++ } + #ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; + #endif +@@ -58,6 +61,7 @@ __vasprintf_internal (char **result_ptr, const char *format, va_list args, + if (ret < 0) + { + free (sf._sbf._f._IO_buf_base); ++ *result_ptr = NULL; + return ret; + } + /* Only use realloc if the size we need is of the same (binary) +diff --git a/manual/stdio.texi b/manual/stdio.texi +index 01fa2d0ffdbd6f5f..90e720aeebc8142c 100644 +--- a/manual/stdio.texi ++++ b/manual/stdio.texi +@@ -2536,7 +2536,14 @@ Allocation}) to hold the output, instead of putting the output in a + buffer you allocate in advance. The @var{ptr} argument should be the + address of a @code{char *} object, and a successful call to + @code{asprintf} stores a pointer to the newly allocated string at that +-location. ++location. Current and future versions of @theglibc{} write a null ++pointer to @samp{*@var{ptr}} upon failure. To achieve similar ++behavior with previous versions, initialize @samp{*@var{ptr}} to a ++null pointer before calling @code{asprintf}. (Specifications for ++@code{asprintf} only require a valid pointer value in ++@samp{*@var{ptr}} if @code{asprintf} succeeds, but no implementations ++are known which overwrite a null pointer with a pointer that cannot be ++freed on failure.) + + The return value is the number of characters allocated for the buffer, or + less than zero if an error occurred. Usually this means that the buffer diff --git a/glibc.spec b/glibc.spec index d433745..7be1b0e 100644 --- a/glibc.spec +++ b/glibc.spec @@ -157,7 +157,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 231%{?dist} +Release: 232%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -1341,6 +1341,7 @@ Patch1025: glibc-RHEL-104852-2.patch Patch1026: glibc-RHEL-106206.patch Patch1027: glibc-RHEL-108220.patch Patch1028: glibc-RHEL-107518.patch +Patch1029: glibc-RHEL-72245.patch ############################################################################## # Continued list of core "glibc" package information: @@ -3428,6 +3429,9 @@ update_gconv_modules_cache () %endif %changelog +* Tue Sep 02 2025 Arjun Shankar - 2.34-232 +- libio: Upon asprintf failure set the string pointer to NULL (RHEL-72245) + * Tue Aug 19 2025 Arjun Shankar - 2.34-231 - Define __libc_tsd_CTYPE_* TLS variables as initial-exec (RHEL-107518)