libio: Upon asprintf failure set the string pointer to NULL (RHEL-72245)
Resolves: RHEL-72245
This commit is contained in:
parent
faa64d329c
commit
1d21eb187f
151
glibc-RHEL-72245.patch
Normal file
151
glibc-RHEL-72245.patch
Normal file
@ -0,0 +1,151 @@
|
||||
commit cb4692ce1edd5a81c2521de49dfef6125141d1c7
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
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
|
||||
<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>
|
||||
|
||||
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
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <stdio.h>
|
||||
+#include <support/check.h>
|
||||
+#include <sys/resource.h>
|
||||
+
|
||||
+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 <support/test-driver.c>
|
||||
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
|
||||
@ -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 <arjun@redhat.com> - 2.34-232
|
||||
- libio: Upon asprintf failure set the string pointer to NULL (RHEL-72245)
|
||||
|
||||
* Tue Aug 19 2025 Arjun Shankar <arjun@redhat.com> - 2.34-231
|
||||
- Define __libc_tsd_CTYPE_* TLS variables as initial-exec (RHEL-107518)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user