CVE-2025-15281: wordexp WRDE_REUSE uninitialized memory read (RHEL-142787)
Resolves: RHEL-142787
This commit is contained in:
parent
383c532ed6
commit
99ea5077f6
174
glibc-RHEL-142787-1.patch
Normal file
174
glibc-RHEL-142787-1.patch
Normal file
@ -0,0 +1,174 @@
|
||||
commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302
|
||||
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
Date: Thu Jan 15 10:32:19 2026 -0300
|
||||
|
||||
posix: Reset wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814)
|
||||
|
||||
The wordexp fails to properly initialize the input wordexp_t when
|
||||
WRDE_REUSE is used. The wordexp_t struct is properly freed, but
|
||||
reuses the old wc_wordc value and updates the we_wordv in the
|
||||
wrong position. A later wordfree will then call free with an
|
||||
invalid pointer.
|
||||
|
||||
Checked on x86_64-linux-gnu and i686-linux-gnu.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
posix/Makefile
|
||||
(Makefile not sorted downstream)
|
||||
|
||||
diff --git a/posix/Makefile b/posix/Makefile
|
||||
index 42a0290370b40fd9..e546b8d667b9c6c4 100644
|
||||
--- a/posix/Makefile
|
||||
+++ b/posix/Makefile
|
||||
@@ -96,7 +96,8 @@ tests := test-errno tstgetopt testfnm runtests runptests \
|
||||
tst-posix_fadvise tst-posix_fadvise64 \
|
||||
tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
|
||||
tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
|
||||
- bug-regex38 tst-regcomp-truncated tst-regcomp-bracket-free
|
||||
+ bug-regex38 tst-regcomp-truncated tst-regcomp-bracket-free \
|
||||
+ tst-wordexp-reuse
|
||||
tests-internal := bug-regex5 bug-regex20 bug-regex33 \
|
||||
tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \
|
||||
tst-glob_lstat_compat tst-spawn4-compat
|
||||
@@ -128,7 +129,8 @@ generated += $(addprefix wordexp-test-result, 1 2 3 4 5 6 7 8 9 10) \
|
||||
tst-boost.mtrace bug-ga2.mtrace bug-ga2-mem.out \
|
||||
bug-glob2.mtrace bug-glob2-mem.out tst-vfork3-mem.out \
|
||||
tst-vfork3.mtrace getconf.speclist tst-fnmatch-mem.out \
|
||||
- tst-fnmatch.mtrace bug-regex36.mtrace
|
||||
+ tst-fnmatch.mtrace bug-regex36.mtrace \
|
||||
+ tst-wordexp-reuse-mem.out tst-wordexp-reuse.mtrace
|
||||
|
||||
ifeq ($(run-built-tests),yes)
|
||||
ifeq (yes,$(build-shared))
|
||||
@@ -146,7 +148,8 @@ tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \
|
||||
$(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
|
||||
$(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
|
||||
$(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out \
|
||||
- $(objpfx)tst-glob-tilde-mem.out
|
||||
+ $(objpfx)tst-glob-tilde-mem.out \
|
||||
+ $(objpfx)tst-wordexp-reuse.out
|
||||
xtests-special += $(objpfx)bug-ga2-mem.out
|
||||
endif
|
||||
|
||||
@@ -387,3 +390,10 @@ $(objpfx)posix-conf-vars-def.h: $(..)scripts/gen-posix-conf-vars.awk \
|
||||
$(make-target-directory)
|
||||
$(AWK) -f $(filter-out Makefile, $^) > $@.tmp
|
||||
mv -f $@.tmp $@
|
||||
+
|
||||
+tst-wordexp-reuse-ENV += MALLOC_TRACE=$(objpfx)tst-wordexp-reuse.mtrace \
|
||||
+ LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
|
||||
+
|
||||
+$(objpfx)tst-wordexp-reuse-mem.out: $(objpfx)tst-wordexp-reuse.out
|
||||
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-wordexp-reuse.mtrace > $@; \
|
||||
+ $(evaluate-test)
|
||||
diff --git a/posix/tst-wordexp-reuse.c b/posix/tst-wordexp-reuse.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3926b9f5576750ac
|
||||
--- /dev/null
|
||||
+++ b/posix/tst-wordexp-reuse.c
|
||||
@@ -0,0 +1,89 @@
|
||||
+/* Test for wordexp with WRDE_REUSE flag.
|
||||
+ Copyright (C) 2026 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 <wordexp.h>
|
||||
+#include <mcheck.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ mtrace ();
|
||||
+
|
||||
+ {
|
||||
+ wordexp_t p = { 0 };
|
||||
+ TEST_COMPARE (wordexp ("one", &p, 0), 0);
|
||||
+ TEST_COMPARE (p.we_wordc, 1);
|
||||
+ TEST_COMPARE_STRING (p.we_wordv[0], "one");
|
||||
+ TEST_COMPARE (wordexp ("two", &p, WRDE_REUSE), 0);
|
||||
+ TEST_COMPARE (p.we_wordc, 1);
|
||||
+ TEST_COMPARE_STRING (p.we_wordv[0], "two");
|
||||
+ wordfree (&p);
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ wordexp_t p = { .we_offs = 2 };
|
||||
+ TEST_COMPARE (wordexp ("one", &p, 0), 0);
|
||||
+ TEST_COMPARE (p.we_wordc, 1);
|
||||
+ TEST_COMPARE_STRING (p.we_wordv[0], "one");
|
||||
+ TEST_COMPARE (wordexp ("two", &p, WRDE_REUSE | WRDE_DOOFFS), 0);
|
||||
+ TEST_COMPARE (p.we_wordc, 1);
|
||||
+ TEST_COMPARE_STRING (p.we_wordv[p.we_offs + 0], "two");
|
||||
+ wordfree (&p);
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ wordexp_t p = { 0 };
|
||||
+ TEST_COMPARE (wordexp ("one", &p, 0), 0);
|
||||
+ TEST_COMPARE (p.we_wordc, 1);
|
||||
+ TEST_COMPARE_STRING (p.we_wordv[0], "one");
|
||||
+ TEST_COMPARE (wordexp ("two", &p, WRDE_REUSE | WRDE_APPEND), 0);
|
||||
+ TEST_COMPARE (p.we_wordc, 1);
|
||||
+ TEST_COMPARE_STRING (p.we_wordv[0], "two");
|
||||
+ wordfree (&p);
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ wordexp_t p = { .we_offs = 2 };
|
||||
+ TEST_COMPARE (wordexp ("one", &p, WRDE_DOOFFS), 0);
|
||||
+ TEST_COMPARE (p.we_wordc, 1);
|
||||
+ TEST_COMPARE_STRING (p.we_wordv[p.we_offs + 0], "one");
|
||||
+ TEST_COMPARE (wordexp ("two", &p, WRDE_REUSE
|
||||
+ | WRDE_DOOFFS), 0);
|
||||
+ TEST_COMPARE (p.we_wordc, 1);
|
||||
+ TEST_COMPARE_STRING (p.we_wordv[p.we_offs + 0], "two");
|
||||
+ wordfree (&p);
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ wordexp_t p = { .we_offs = 2 };
|
||||
+ TEST_COMPARE (wordexp ("one", &p, WRDE_DOOFFS), 0);
|
||||
+ TEST_COMPARE (p.we_wordc, 1);
|
||||
+ TEST_COMPARE_STRING (p.we_wordv[p.we_offs + 0], "one");
|
||||
+ TEST_COMPARE (wordexp ("two", &p, WRDE_REUSE
|
||||
+ | WRDE_DOOFFS | WRDE_APPEND), 0);
|
||||
+ TEST_COMPARE (p.we_wordc, 1);
|
||||
+ TEST_COMPARE_STRING (p.we_wordv[p.we_offs + 0], "two");
|
||||
+ wordfree (&p);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/posix/wordexp.c b/posix/wordexp.c
|
||||
index 4061969c720f1f34..0f503b1877d2ce5b 100644
|
||||
--- a/posix/wordexp.c
|
||||
+++ b/posix/wordexp.c
|
||||
@@ -2241,7 +2241,9 @@ wordexp (const char *words, wordexp_t *pwordexp, int flags)
|
||||
{
|
||||
/* Minimal implementation of WRDE_REUSE for now */
|
||||
wordfree (pwordexp);
|
||||
+ old_word.we_wordc = 0;
|
||||
old_word.we_wordv = NULL;
|
||||
+ pwordexp->we_wordc = 0;
|
||||
}
|
||||
|
||||
if ((flags & WRDE_APPEND) == 0)
|
||||
29
glibc-RHEL-142787-2.patch
Normal file
29
glibc-RHEL-142787-2.patch
Normal file
@ -0,0 +1,29 @@
|
||||
commit bed2db02f3183e93f21d506786c5f884a1dec9e7
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Jan 26 17:12:37 2026 +0100
|
||||
|
||||
posix: Run tst-wordexp-reuse-mem test
|
||||
|
||||
The test was not properly scheduled for execution with a Makefile
|
||||
dependency.
|
||||
|
||||
Fixes commit 80cc58ea2de214f85b0a1d902a3b668ad2ecb302 ("posix: Reset
|
||||
wordexp_t fields with WRDE_REUSE (CVE-2025-15281 / BZ 33814").
|
||||
|
||||
Conflicts:
|
||||
posix/Makefile
|
||||
(Makefile not sorted downstream)
|
||||
|
||||
diff --git a/posix/Makefile b/posix/Makefile
|
||||
index e546b8d667b9c6c4..b399b1dab0a8cb9c 100644
|
||||
--- a/posix/Makefile
|
||||
+++ b/posix/Makefile
|
||||
@@ -149,7 +149,7 @@ tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \
|
||||
$(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
|
||||
$(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out \
|
||||
$(objpfx)tst-glob-tilde-mem.out \
|
||||
- $(objpfx)tst-wordexp-reuse.out
|
||||
+ $(objpfx)tst-wordexp-reuse-mem.out
|
||||
xtests-special += $(objpfx)bug-ga2-mem.out
|
||||
endif
|
||||
|
||||
@ -115,7 +115,7 @@ end \
|
||||
Summary: The GNU libc libraries
|
||||
Name: glibc
|
||||
Version: %{glibcversion}
|
||||
Release: %{glibcrelease}.30
|
||||
Release: %{glibcrelease}.31
|
||||
|
||||
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
||||
# libraries.
|
||||
@ -1297,6 +1297,8 @@ Patch1062: glibc-RHEL-72011-7.patch
|
||||
Patch1063: glibc-RHEL-72011-8.patch
|
||||
Patch1064: glibc-RHEL-141849.patch
|
||||
Patch1065: glibc-RHEL-142194.patch
|
||||
Patch1066: glibc-RHEL-142787-1.patch
|
||||
Patch1067: glibc-RHEL-142787-2.patch
|
||||
|
||||
##############################################################################
|
||||
# Continued list of core "glibc" package information:
|
||||
@ -2958,6 +2960,9 @@ fi
|
||||
%{_libdir}/libpthread_nonshared.a
|
||||
|
||||
%changelog
|
||||
* Mon Jan 26 2026 Florian Weimer <fweimer@redhat.com> - 2.28-251.31
|
||||
- CVE-2025-15281: wordexp WRDE_REUSE uninitialized memory read (RHEL-142787)
|
||||
|
||||
* Mon Jan 19 2026 Florian Weimer <fweimer@redhat.com> - 2.28-251.30
|
||||
- Remove default /var/tmp for LD_PROFILE_OUTPUT (RHEL-142194)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user