CVE-2026-5928: Fix ungetwc operating on byte stream (RHEL-180340)
Resolves: RHEL-180340
This commit is contained in:
parent
ec99e297ec
commit
2acec79102
102
glibc-RHEL-180340.patch
Normal file
102
glibc-RHEL-180340.patch
Normal file
@ -0,0 +1,102 @@
|
||||
commit ef3bfb5f910011f3780cb06aa47e730035f53285
|
||||
Author: Rocket Ma <marocketbd@gmail.com>
|
||||
Date: Fri May 1 20:39:07 2026 -0700
|
||||
|
||||
libio: Fix ungetwc operating on byte stream [BZ #33998]
|
||||
|
||||
* libio/wgenops.c: When _IO_wdefault_pbackfail attempts to push back one
|
||||
character, it accidently compare the wchar to push back with the last
|
||||
char from byte stream, instead of wide stream. Under specific coding,
|
||||
attacker may exploit this to leak information. This commit fix bug
|
||||
33998, or CVE-2026-5928.
|
||||
|
||||
Signed-off-by: Rocket Ma <marocketbd@gmail.com>
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/libio/Makefile b/libio/Makefile
|
||||
index 93656466df..6e0627bb88 100644
|
||||
--- a/libio/Makefile
|
||||
+++ b/libio/Makefile
|
||||
@@ -84,6 +84,7 @@ tests = \
|
||||
bug-ungetwc1 \
|
||||
bug-ungetwc2 \
|
||||
bug-wfflush \
|
||||
+ bug-wgenops-bz33998 \
|
||||
bug-wmemstream1 \
|
||||
bug-wsetpos \
|
||||
test-fmemopen \
|
||||
diff --git a/libio/bug-wgenops-bz33998.c b/libio/bug-wgenops-bz33998.c
|
||||
new file mode 100644
|
||||
index 0000000000..cc4067da99
|
||||
--- /dev/null
|
||||
+++ b/libio/bug-wgenops-bz33998.c
|
||||
@@ -0,0 +1,54 @@
|
||||
+/* Regression test for ungetwc operating on byte stream (BZ #33998)
|
||||
+ Copyright (C) 2026 The GNU Toolchain Authors.
|
||||
+ 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 "support/temp_file.h"
|
||||
+#include "support/xstdio.h"
|
||||
+#include "support/xunistd.h"
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/mman.h>
|
||||
+#include <stdio.h>
|
||||
+#include <wchar.h>
|
||||
+#include <support/check.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ char *filename;
|
||||
+ int fd = create_temp_file ("tst-bz33998-", &filename);
|
||||
+ TEST_VERIFY (fd != -1);
|
||||
+ xwrite (fd, "A", sizeof ("A")); // write "A\0" by design
|
||||
+ xclose (fd);
|
||||
+
|
||||
+ FILE *fp = xfopen (filename, "r+");
|
||||
+ TEST_COMPARE (getwc (fp), L'A');
|
||||
+ /* If the bug is fixed, then ungetwc should not touch byte stream.
|
||||
+ If the bug is not fixed, ungetwc firstly match last read char, L'A',
|
||||
+ failed, then the pbackfail branch, matching last read char in byte
|
||||
+ stream, that is, '\0' (initialized when setup wide stream). */
|
||||
+ char *old_read_ptr = fp->_IO_read_ptr;
|
||||
+ TEST_COMPARE (ungetwc (L'\0', fp), L'\0');
|
||||
+ TEST_VERIFY (fp->_IO_read_ptr == old_read_ptr);
|
||||
+
|
||||
+ xfclose (fp);
|
||||
+ free (filename);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/libio/wgenops.c b/libio/wgenops.c
|
||||
index 6829477e0c..5f36bc49a1 100644
|
||||
--- a/libio/wgenops.c
|
||||
+++ b/libio/wgenops.c
|
||||
@@ -110,8 +110,8 @@ _IO_wdefault_pbackfail (FILE *fp, wint_t c)
|
||||
{
|
||||
if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
|
||||
&& !_IO_in_backup (fp)
|
||||
- && (wint_t) fp->_IO_read_ptr[-1] == c)
|
||||
- --fp->_IO_read_ptr;
|
||||
+ && (wint_t) fp->_wide_data->_IO_read_ptr[-1] == c)
|
||||
+ --fp->_wide_data->_IO_read_ptr;
|
||||
else
|
||||
{
|
||||
/* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
|
||||
Loading…
Reference in New Issue
Block a user