Fix memory leak after fdopen seek failure

- Backport: Remove memory leak in fdopen (bug 31840)
- Backport: libio: Test for fdopen memory leak without SEEK_END
  support (bug 31840)

Resolves: RHEL-108475
This commit is contained in:
Frédéric Bérat 2025-08-11 14:20:42 +02:00
parent 46a31fdf25
commit d19eb70013
3 changed files with 154 additions and 1 deletions

28
glibc-RHEL-108475-1.patch Normal file
View File

@ -0,0 +1,28 @@
commit b2c3ee3724900975deaf5eae57640bb0c2d7315e
Author: Andreas Schwab <schwab@suse.de>
Date: Tue Jun 4 11:01:11 2024 +0200
Remove memory leak in fdopen (bug 31840)
Deallocate the memory for the FILE structure when seeking to the end fails
in append mode.
Fixes: ea33158c96 ("Fix offset caching for streams and use it for ftell (BZ #16680)")
diff --git a/libio/iofdopen.c b/libio/iofdopen.c
index 2583fb825573aae4..14fbc7b257ad7724 100644
--- a/libio/iofdopen.c
+++ b/libio/iofdopen.c
@@ -156,7 +156,11 @@ _IO_new_fdopen (int fd, const char *mode)
{
off64_t new_pos = _IO_SYSSEEK (&new_f->fp.file, 0, _IO_seek_end);
if (new_pos == _IO_pos_BAD && errno != ESPIPE)
- return NULL;
+ {
+ _IO_un_link (&new_f->fp);
+ free (new_f);
+ return NULL;
+ }
}
return &new_f->fp.file;
}

120
glibc-RHEL-108475-2.patch Normal file
View File

@ -0,0 +1,120 @@
commit d0106b6ae26c8cc046269358a77188105c99d5e3
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue Jun 4 14:37:35 2024 +0200
libio: Test for fdopen memory leak without SEEK_END support (bug 31840)
The bug report used /dev/mem, but /proc/self/mem works as well
(if available).
diff --git a/libio/Makefile b/libio/Makefile
index 92d6c6bcab1818d0..b189455bb9b8fd1b 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -94,6 +94,7 @@ tests = \
tst-eof \
tst-ext \
tst-ext2 \
+ tst-fdopen-seek-failure \
tst-fgetc-after-eof \
tst-fgetwc \
tst-fgetws \
@@ -253,6 +254,9 @@ tst_wprintf2-ARGS = "Some Text"
test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace \
LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
+tst-fdopen-seek-failure-ENV = \
+ MALLOC_TRACE=$(objpfx)tst-fdopen-seek-failure.mtrace \
+ LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace \
LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace \
@@ -261,6 +265,7 @@ tst-bz24228-ENV = MALLOC_TRACE=$(objpfx)tst-bz24228.mtrace \
LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
generated += test-fmemopen.mtrace test-fmemopen.check
+generated += tst-fdopen-seek-failure.mtrace tst-fdopen-seek-failure.check
generated += tst-fopenloc.mtrace tst-fopenloc.check
generated += tst-bz22415.mtrace tst-bz22415.check
@@ -283,8 +288,12 @@ shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops \
oldiofsetpos64
ifeq ($(run-built-tests),yes)
-tests-special += $(objpfx)test-freopen.out $(objpfx)test-fmemopen-mem.out \
- $(objpfx)tst-bz22415-mem.out
+tests-special += \
+ $(objpfx)test-fmemopen-mem.out \
+ $(objpfx)test-freopen.out \
+ $(objpfx)tst-bz22415-mem.out \
+ $(objpfx)tst-fdopen-seek-failure-mem.out \
+ # tests-special
ifeq (yes,$(build-shared))
# Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared
# library is enabled since they depend on tst-fopenloc.out.
@@ -372,6 +381,11 @@ $(objpfx)test-fmemopen-mem.out: $(objpfx)test-fmemopen.out
$(common-objpfx)malloc/mtrace $(objpfx)test-fmemopen.mtrace > $@; \
$(evaluate-test)
+$(objpfx)tst-fdopen-seek-failure-mem.out: $(objpfx)tst-fdopen-seek-failure.out
+ $(common-objpfx)malloc/mtrace \
+ $(objpfx)tst-fdopen-seek-failure.mtrace > $@; \
+ $(evaluate-test)
+
$(objpfx)tst-fopenloc-mem.out: $(objpfx)tst-fopenloc.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-fopenloc.mtrace > $@; \
$(evaluate-test)
diff --git a/libio/tst-fdopen-seek-failure.c b/libio/tst-fdopen-seek-failure.c
new file mode 100644
index 0000000000000000..5c4d40ab34158571
--- /dev/null
+++ b/libio/tst-fdopen-seek-failure.c
@@ -0,0 +1,48 @@
+/* Test for fdopen memory leak without SEEK_END support (bug 31840).
+ 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 <fcntl.h>
+#include <mcheck.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <support/check.h>
+#include <support/xunistd.h>
+#include <unistd.h>
+
+static int
+do_test (void)
+{
+ mtrace ();
+
+ /* This file is special because it is seekable, but only
+ with SEEK_SET, not SEEK_END. */
+ int fd = open ("/proc/self/mem", O_RDWR);
+ if (fd < 0)
+ FAIL_UNSUPPORTED ("/proc/self/mem not found: %m");
+ FILE *fp = fdopen (fd, "a");
+ /* The fdopen call should have failed because it tried to use
+ SEEK_END. */
+ TEST_VERIFY (fp == NULL);
+ TEST_COMPARE (errno, EINVAL);
+ xclose (fd);
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -147,7 +147,7 @@ Version: %{glibcversion}
# - It allows using the Release number without the %%dist tag in the dependency
# generator to make the generated requires interchangeable between Rawhide
# and ELN (.elnYY < .fcXX).
%global baserelease 53
%global baserelease 54
Release: %{baserelease}%{?dist}
# Licenses:
@ -649,6 +649,8 @@ Patch323: glibc-RHEL-107695-16.patch
Patch324: glibc-RHEL-107695-17.patch
Patch325: glibc-RHEL-107695-18.patch
Patch326: glibc-RHEL-107695-19.patch
Patch327: glibc-RHEL-108475-1.patch
Patch328: glibc-RHEL-108475-2.patch
##############################################################################
# Continued list of core "glibc" package information:
@ -2662,6 +2664,9 @@ update_gconv_modules_cache ()
%endif
%changelog
* Mon Aug 11 2025 Frédéric Bérat <fberat@redhat.com> - 2.39-54
- Fix memory leak after fdopen seek failure (RHEL-108475)
* Wed Aug 06 2025 Frédéric Bérat <fberat@redhat.com> - 2.39-53
- Updated glibc to support Linux 6.15 kernel system calls and constants.
(RHEL-107695)