From 33cd6cd1d392a75012404eb8dc102c316c0942e4 Mon Sep 17 00:00:00 2001 From: AlmaLinux RelEng Bot Date: Mon, 29 Jun 2026 11:56:59 -0400 Subject: [PATCH] import CS git glibc-2.28-251.el8_10.38 --- SOURCES/glibc-RHEL-172700-1.patch | 127 +++++++++ SOURCES/glibc-RHEL-172700-2.patch | 72 +++++ SOURCES/glibc-RHEL-172700-3.patch | 456 ++++++++++++++++++++++++++++++ SOURCES/glibc-RHEL-172700-4.patch | 208 ++++++++++++++ SPECS/glibc.spec | 9 +- 5 files changed, 871 insertions(+), 1 deletion(-) create mode 100644 SOURCES/glibc-RHEL-172700-1.patch create mode 100644 SOURCES/glibc-RHEL-172700-2.patch create mode 100644 SOURCES/glibc-RHEL-172700-3.patch create mode 100644 SOURCES/glibc-RHEL-172700-4.patch diff --git a/SOURCES/glibc-RHEL-172700-1.patch b/SOURCES/glibc-RHEL-172700-1.patch new file mode 100644 index 0000000..09e7b84 --- /dev/null +++ b/SOURCES/glibc-RHEL-172700-1.patch @@ -0,0 +1,127 @@ +commit 839898777226a3ed88c0859f25ffe712519b4ead +Author: Rocket Ma +Date: Fri Apr 17 23:48:41 2026 -0700 + + stdio-common: Fix buffer overflow in scanf %mc [BZ #34008] + + * stdio-common/vfscanf-internal.c: When enlarging allocated buffer with + format %mc or %mC, glibc allocates one byte less, leading to + user-controlled one byte overflow. This commit fixes BZ #34008, or + CVE-2026-5450. + + Reviewed-by: Carlos O'Donell + Signed-off-by: Rocket Ma + Reviewed-by: H.J. Lu + +Conflicts: + stdio-common/Makefile + (fixup context) + stdio-common/vfscanf.c + (vfscanf_internal is part of vfscanf.c) + +diff -Nrup a/stdio-common/Makefile b/stdio-common/Makefile +--- a/stdio-common/Makefile 2026-06-02 13:10:51.282023845 -0400 ++++ b/stdio-common/Makefile 2026-06-02 13:10:33.565576212 -0400 +@@ -65,6 +65,7 @@ tests := tstscanf test_rdwr test-popen t + tst-renameat2 \ + tst-printf-bz25691 \ + tst-vfprintf-width-prec-alloc \ ++ tst-vfscanf-bz34008 \ + tst-grouping2 \ + # tests + +@@ -103,6 +104,9 @@ endif + tst-printf-bz18872-ENV = MALLOC_TRACE=$(objpfx)tst-printf-bz18872.mtrace + tst-vfprintf-width-prec-ENV = \ + MALLOC_TRACE=$(objpfx)tst-vfprintf-width-prec.mtrace ++tst-vfscanf-bz34008-ENV = \ ++ MALLOC_CHECK_=3 \ ++ LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so + tst-printf-bz25691-ENV = \ + MALLOC_TRACE=$(objpfx)tst-printf-bz25691.mtrace + +diff --git a/stdio-common/tst-vfscanf-bz34008.c b/stdio-common/tst-vfscanf-bz34008.c +new file mode 100644 +index 0000000000..48371c8a3d +--- /dev/null ++++ b/stdio-common/tst-vfscanf-bz34008.c +@@ -0,0 +1,48 @@ ++/* Regression test for vfscanf %Nmc out-of-bound write (BZ #34008) ++ 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 ++ . */ ++ ++#include "malloc/mcheck.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define WIDTH 0x410 ++#define SCANFSTR "%1040mc" ++static int ++do_test (void) ++{ ++ mcheck_pedantic (NULL); ++ char *input = malloc (WIDTH + 1); ++ TEST_VERIFY (input != NULL); ++ memset (input, 'A', WIDTH); ++ input[WIDTH] = '\0'; ++ ++ char *buf = NULL; ++ TEST_VERIFY (sscanf (input, SCANFSTR, &buf) != -1); ++ TEST_VERIFY (buf != NULL); ++ ++ free (buf); ++ free (input); ++ return 0; ++} ++ ++#include +diff -Nrup a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c +--- a/stdio-common/vfscanf.c 2018-08-01 01:10:47.000000000 -0400 ++++ b/stdio-common/vfscanf.c 2026-06-02 13:29:00.213769470 -0400 +@@ -804,8 +804,7 @@ _IO_vfscanf_internal (FILE *s, const cha + { + /* Enlarge the buffer. */ + size_t newsize +- = strsize +- + (strsize >= width ? width - 1 : strsize); ++ = strsize + (strsize >= width ? width : strsize); + + str = (char *) realloc (*strptr, newsize); + if (str == NULL) +@@ -876,7 +875,7 @@ _IO_vfscanf_internal (FILE *s, const cha + && wstr == (wchar_t *) *strptr + strsize) + { + size_t newsize +- = strsize + (strsize > width ? width - 1 : strsize); ++ = strsize + (strsize >= width ? width : strsize); + /* Enlarge the buffer. */ + wstr = (wchar_t *) realloc (*strptr, + newsize * sizeof (wchar_t)); +@@ -931,7 +930,7 @@ _IO_vfscanf_internal (FILE *s, const cha + && wstr == (wchar_t *) *strptr + strsize) + { + size_t newsize +- = strsize + (strsize > width ? width - 1 : strsize); ++ = strsize + (strsize >= width ? width : strsize); + /* Enlarge the buffer. */ + wstr = (wchar_t *) realloc (*strptr, + newsize * sizeof (wchar_t)); diff --git a/SOURCES/glibc-RHEL-172700-2.patch b/SOURCES/glibc-RHEL-172700-2.patch new file mode 100644 index 0000000..a0ee402 --- /dev/null +++ b/SOURCES/glibc-RHEL-172700-2.patch @@ -0,0 +1,72 @@ +commit b866ef29773b22a1343ff9084374775114350b78 +Author: Maciej W. Rozycki +Date: Wed May 27 12:57:10 2026 -0400 + + support: Implement 'xfmemopen' for seamless 'fmemopen' use + + Add 'xfmemopen' wrapper for seamless 'fmemopen' use in tests, following + 'xfopen', 'xfclose', etc., and providing a standardized error reporting + facility. + + Reviewed-by: Florian Weimer + (cherry picked from commit fe709cc24578ecfd2ff5b07e10e3829fcb55075b) + + Reviewed-by: Carlos O'Donell + +diff -Nrup a/support/Makefile b/support/Makefile +--- a/support/Makefile 2026-06-03 15:34:26.197170635 -0400 ++++ b/support/Makefile 2026-06-03 15:32:18.982705260 -0400 +@@ -97,6 +97,7 @@ libsupport-routines = \ + xdup2 \ + xfchmod \ + xfclose \ ++ xfmemopen \ + xfopen \ + xfork \ + xftruncate \ +diff -Nrup a/support/xfmemopen.c b/support/xfmemopen.c +--- a/support/xfmemopen.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/support/xfmemopen.c 2026-06-03 15:29:07.233027461 -0400 +@@ -0,0 +1,31 @@ ++/* fmemopen with error checking. ++ Copyright (C) 2025 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 ++ ++FILE * ++xfmemopen (void *mem, size_t len, const char *mode) ++{ ++ FILE *fp = fmemopen (mem, len, mode); ++ if (fp == NULL) ++ FAIL_EXIT1 ("fmemopen (mode \"%s\"): %m", mode); ++ return fp; ++} +diff -Nrup a/support/xstdio.h b/support/xstdio.h +--- a/support/xstdio.h 2026-06-03 15:34:20.164172744 -0400 ++++ b/support/xstdio.h 2026-06-03 15:33:23.666408244 -0400 +@@ -26,6 +26,7 @@ __BEGIN_DECLS + + FILE *xfopen (const char *path, const char *mode); + void xfclose (FILE *); ++FILE *xfmemopen (void *mem, size_t len, const char *mode); + + /* Read a line from FP, using getline. *BUFFER must be NULL, or a + heap-allocated pointer of *LENGTH bytes. Return the number of diff --git a/SOURCES/glibc-RHEL-172700-3.patch b/SOURCES/glibc-RHEL-172700-3.patch new file mode 100644 index 0000000..24deed1 --- /dev/null +++ b/SOURCES/glibc-RHEL-172700-3.patch @@ -0,0 +1,456 @@ +commit 97926e9017f3faeaacce9337f1288460f5e6ec7d +Author: Maciej W. Rozycki +Date: Wed May 27 12:57:10 2026 -0400 + + stdio-common: Reject insufficient character data in scanf [BZ #12701] + + Reject invalid formatted scanf character data with the 'c' conversion + where there is not enough input available to satisfy the field width + requested. It is required by ISO C that this conversion matches a + sequence of characters of exactly the number specified by the field + width and it is also already documented as such in our own manual: + + "It reads precisely the next N characters, and fails if it cannot get + that many." + + Currently a matching success is instead incorrectly produced where the + EOF condition is encountered before the required number of characters + has been retrieved, and the characters actually obtained are stored in + the buffer provided. + + Add test cases accordingly and remove placeholders from 'c' conversion + input data for the existing scanf tests. + + Reviewed-by: Adhemerval Zanella + + [This is a modified version of commit 2b16c76609, which tests for the + old behavior and only includes the test cases, for older branches + and downstream backports - DJ] + + Reviewed-by: Carlos O'Donell + +Conflicts: + localedata/Makefile + (usual lay-out differences) + stdio-common/Makefile + (usual lay-out differences) + +diff -Nrup a/localedata/Makefile b/localedata/Makefile +--- a/localedata/Makefile 2026-06-03 12:13:30.441073814 -0400 ++++ b/localedata/Makefile 2026-06-03 12:15:32.566080395 -0400 +@@ -154,7 +154,7 @@ locale_test_suite := tst_iswalnum tst_is + + tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \ + tst-leaks tst-mbswcs1 tst-mbswcs2 tst-mbswcs3 tst-mbswcs4 tst-mbswcs5 \ +- tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \ ++ tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale tst-bz12701-lc \ + tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3 \ + tst-wctype + tests-static = bug-setlocale1-static +diff -Nrup a/localedata/tst-bz12701-lc.c b/localedata/tst-bz12701-lc.c +--- a/localedata/tst-bz12701-lc.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/localedata/tst-bz12701-lc.c 2026-06-03 12:12:56.929422368 -0400 +@@ -0,0 +1,218 @@ ++/* Verify scanf field width handling with the 'lc' conversion (BZ #12701). ++ Copyright (C) 2025-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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* Compare character-wise the initial part of the wide character object ++ pointed to by WS corresponding to wide characters obtained by the ++ conversion of first N bytes of the multibyte character object pointed ++ to by S. */ ++ ++static int ++tst_bz12701_lc_memcmp (const wchar_t *ds, const char *s, size_t n) ++{ ++ size_t nc = mbsnrtowcs (NULL, &s, n, 0, NULL); ++ ++ struct support_next_to_fault ntf; ++ ntf = support_next_to_fault_allocate (nc * sizeof (wchar_t)); ++ wchar_t *ss = (wchar_t *) ntf.buffer; ++ ++ mbsnrtowcs (ss, &s, n, nc, NULL); ++ int r = wmemcmp (ds, ss, nc); ++ ++ support_next_to_fault_free (&ntf); ++ ++ return r; ++} ++ ++/* Verify various aspects of field width handling, including the data ++ obtained, the number of bytes consumed, and the stream position. */ ++ ++static int ++do_test (void) ++{ ++ if (setlocale (LC_ALL, "pl_PL.UTF-8") == NULL) ++ FAIL_EXIT1 ("setlocale (LC_ALL, \"pl_PL.UTF-8\")"); ++ ++ /* Part of a tongue-twister in Polish, which says: ++ "On a rainy morning cuckoos and warblers, rather than starting ++ on earthworms, stuffed themselves fasted with the flesh of cress." */ ++ static const char s[126] = "Dżdżystym rankiem gżegżółki i piegże, " ++ "zamiast wziąć się za dżdżownice, " ++ "nażarły się na czczo miąższu rzeżuchy"; ++ ++ const char *sp = s; ++ size_t nc; ++ TEST_VERIFY_EXIT ((nc = mbsnrtowcs (NULL, &sp, sizeof (s), 0, NULL)) == 108); ++ ++ struct support_next_to_fault ntfo, ntfi; ++ ntfo = support_next_to_fault_allocate (nc * sizeof (wchar_t)); ++ ntfi = support_next_to_fault_allocate (sizeof (s)); ++ wchar_t *e = (wchar_t *) ntfo.buffer + nc; ++ char *b = ntfi.buffer; ++ ++ wchar_t *c; ++ FILE *f; ++ int ic; ++ int n; ++ int i; ++ ++ memcpy (ntfi.buffer, s, sizeof (s)); ++ ++ ic = i = 0; ++ f = xfmemopen (b, sizeof (s), "r"); ++ ++ c = e - 1; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ /* Avoid: "warning: zero width in gnu_scanf format [-Werror=format=]". */ ++ DIAG_PUSH_NEEDS_COMMENT; ++ DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); ++ TEST_VERIFY_EXIT (fscanf (f, "%0lc%n", c, &n) == 1); ++ DIAG_POP_NEEDS_COMMENT; ++ TEST_VERIFY_EXIT (n == 1); ++ TEST_VERIFY_EXIT (tst_bz12701_lc_memcmp (c, s + i, n) == 0); ++ ic += 1; ++ i += n; ++ ++ c = e - 1; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%lc%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 2); ++ TEST_VERIFY_EXIT (tst_bz12701_lc_memcmp (c, s + i, n) == 0); ++ ic += 1; ++ i += n; ++ ++ c = e - 1; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%1lc%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 1); ++ TEST_VERIFY_EXIT (tst_bz12701_lc_memcmp (c, s + i, n) == 0); ++ ic += 1; ++ i += n; ++ ++ c = e - 2; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%2lc%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 3); ++ TEST_VERIFY_EXIT (tst_bz12701_lc_memcmp (c, s + i, n) == 0); ++ ic += 2; ++ i += n; ++ ++ c = e - 4; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%4lc%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 4); ++ TEST_VERIFY_EXIT (tst_bz12701_lc_memcmp (c, s + i, n) == 0); ++ ic += 4; ++ i += n; ++ ++ c = e - 8; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%8lc%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 8); ++ TEST_VERIFY_EXIT (tst_bz12701_lc_memcmp (c, s + i, n) == 0); ++ ic += 8; ++ i += n; ++ ++ c = e - 16; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%16lc%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 20); ++ TEST_VERIFY_EXIT (tst_bz12701_lc_memcmp (c, s + i, n) == 0); ++ ic += 16; ++ i += n; ++ ++ c = e - 32; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%32lc%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 38); ++ TEST_VERIFY_EXIT (tst_bz12701_lc_memcmp (c, s + i, n) == 0); ++ ic += 32; ++ i += n; ++ ++ c = e - (nc - ic); ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_COMPARE (fscanf (f, "%64lc%n", c, &n), 1); ++ TEST_COMPARE (n , 49); ++ TEST_VERIFY_EXIT (tst_bz12701_lc_memcmp (c, s + i, sizeof (s) - i) == 0); ++ ++ TEST_VERIFY_EXIT (ftell (f) == sizeof (s)); ++ TEST_VERIFY_EXIT (feof (f) != 0); ++ ++ xfclose (f); ++ ++ ic = i = 0; ++ f = xfmemopen (b, 3, "r"); ++ ++ c = e - 2; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%2lc%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 3); ++ TEST_VERIFY_EXIT (tst_bz12701_lc_memcmp (c, s + i, n) == 0); ++ ic += 2; ++ i += n; ++ ++ c = e - (nc - ic); ++ TEST_VERIFY_EXIT (feof (f) == 0); ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%2lc%n", c, &n) == EOF); ++ TEST_VERIFY_EXIT (n == 3); ++ ++ TEST_VERIFY_EXIT (ftell (f) == 3); ++ TEST_VERIFY_EXIT (feof (f) != 0); ++ ++ xfclose (f); ++ ++ ic = i = 0; ++ f = xfmemopen (b, 3, "r"); ++ ++ c = e - 1; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%lc%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 1); ++ TEST_VERIFY_EXIT (tst_bz12701_lc_memcmp (c, s + i, n) == 0); ++ ic += 1; ++ i += n; ++ ++ c = e - (nc - ic); ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%2lc%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 2); ++ TEST_VERIFY_EXIT (tst_bz12701_lc_memcmp (c, s + i, 3 - i) == 0); ++ ++ TEST_VERIFY_EXIT (ftell (f) == 3); ++ TEST_VERIFY_EXIT (feof (f) != 0); ++ ++ xfclose (f); ++ ++ support_next_to_fault_free (&ntfi); ++ support_next_to_fault_free (&ntfo); ++ ++ return 0; ++} ++ ++#include +diff -Nrup a/stdio-common/Makefile b/stdio-common/Makefile +--- a/stdio-common/Makefile 2026-06-03 12:13:35.562066297 -0400 ++++ b/stdio-common/Makefile 2026-06-03 12:18:20.481891652 -0400 +@@ -49,7 +49,7 @@ tests := tstscanf test_rdwr test-popen t + bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 \ + tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \ + scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \ +- scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf \ ++ scanf11 scanf12 tst-tmpnam tst-bz12701-c tst-cookie tst-obprintf tst-sscanf \ + tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \ + tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 \ + tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \ +diff -Nrup a/stdio-common/tst-bz12701-c.c b/stdio-common/tst-bz12701-c.c +--- a/stdio-common/tst-bz12701-c.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/stdio-common/tst-bz12701-c.c 2026-06-03 12:12:56.929700530 -0400 +@@ -0,0 +1,169 @@ ++/* Verify scanf field width handling with the 'c' conversion (BZ #12701). ++ Copyright (C) 2025-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 ++ . */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* Verify various aspects of field width handling, including the data ++ obtained, the number of bytes consumed, and the stream position. */ ++ ++static int ++do_test (void) ++{ ++ static const char s[43] = "The quick brown fox jumps over the lazy dog"; ++ struct support_next_to_fault ntfo, ntfi; ++ ntfo = support_next_to_fault_allocate (sizeof (s)); ++ ntfi = support_next_to_fault_allocate (sizeof (s)); ++ char *e = ntfo.buffer + sizeof (s); ++ char *b = ntfi.buffer; ++ ++ char *c; ++ FILE *f; ++ int n; ++ int i; ++ ++ memcpy (ntfi.buffer, s, sizeof (s)); ++ ++ i = 0; ++ f = xfmemopen (b, sizeof (s), "r"); ++ ++ c = e - 1; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ /* Avoid: "warning: zero width in gnu_scanf format [-Werror=format=]". */ ++ DIAG_PUSH_NEEDS_COMMENT; ++ DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat"); ++ TEST_VERIFY_EXIT (fscanf (f, "%0c%n", c, &n) == 1); ++ DIAG_POP_NEEDS_COMMENT; ++ TEST_VERIFY_EXIT (n == 1); ++ TEST_VERIFY_EXIT (memcmp (c, s + i, n) == 0); ++ i += n; ++ ++ c = e - 1; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%c%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 1); ++ TEST_VERIFY_EXIT (memcmp (c, s + i, n) == 0); ++ i += n; ++ ++ c = e - 1; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%1c%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 1); ++ TEST_VERIFY_EXIT (memcmp (c, s + i, n) == 0); ++ i += n; ++ ++ c = e - 2; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%2c%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 2); ++ TEST_VERIFY_EXIT (memcmp (c, s + i, n) == 0); ++ i += n; ++ ++ c = e - 4; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%4c%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 4); ++ TEST_VERIFY_EXIT (memcmp (c, s + i, n) == 0); ++ i += n; ++ ++ c = e - 8; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%8c%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 8); ++ TEST_VERIFY_EXIT (memcmp (c, s + i, n) == 0); ++ i += n; ++ ++ c = e - 16; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%16c%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 16); ++ TEST_VERIFY_EXIT (memcmp (c, s + i, n) == 0); ++ i += n; ++ ++ c = e - (sizeof (s) - i); ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%32c%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 10); ++ TEST_VERIFY_EXIT (memcmp (c, s + i, sizeof (s) - i) == 0); ++ ++ TEST_VERIFY_EXIT (ftell (f) == sizeof (s)); ++ TEST_VERIFY_EXIT (feof (f) != 0); ++ ++ xfclose (f); ++ ++ i = 0; ++ f = xfmemopen (b, 3, "r"); ++ ++ c = e - 1; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%c%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 1); ++ TEST_VERIFY_EXIT (memcmp (c, s + i, n) == 0); ++ i += n; ++ ++ c = e - 2; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%2c%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 2); ++ TEST_VERIFY_EXIT (memcmp (c, s + i, n) == 0); ++ i += n; ++ ++ c = e - (3 - i); ++ TEST_VERIFY_EXIT (feof (f) == 0); ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%2c%n", c, &n) == EOF); ++ TEST_VERIFY_EXIT (n == 2); ++ ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (feof (f) != 0); ++ ++ xfclose (f); ++ ++ i = 0; ++ f = xfmemopen (b, 3, "r"); ++ ++ c = e - 2; ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%2c%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 2); ++ TEST_VERIFY_EXIT (memcmp (c, s + i, n) == 0); ++ i += n; ++ ++ c = e - (3 - i); ++ TEST_VERIFY_EXIT (ftell (f) == i); ++ TEST_VERIFY_EXIT (fscanf (f, "%2c%n", c, &n) == 1); ++ TEST_VERIFY_EXIT (n == 1); ++ TEST_VERIFY_EXIT (memcmp (c, s + i, 3 - i) == 0); ++ ++ TEST_VERIFY_EXIT (ftell (f) == 3); ++ TEST_VERIFY_EXIT (feof (f) != 0); ++ ++ xfclose (f); ++ ++ support_next_to_fault_free (&ntfi); ++ support_next_to_fault_free (&ntfo); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-RHEL-172700-4.patch b/SOURCES/glibc-RHEL-172700-4.patch new file mode 100644 index 0000000..b964299 --- /dev/null +++ b/SOURCES/glibc-RHEL-172700-4.patch @@ -0,0 +1,208 @@ +commit 6cebb0b80fd783e442a8ad27c3f52cde52a9cac7 +Author: DJ Delorie +Date: Wed May 27 12:57:10 2026 -0400 + + stdio-common: Allow partially-filled %mc buffers [BZ #12701] + + This is a backwards-compatible alternative to the main solution to + the %mc part of 12701. The allocated buffer is expanded to the + requested size and NUL padded, but truncated reads are allowed. + + Reviewed-by: Carlos O'Donell + +Conflicts: + localedata/Makefile + (usual lay-out differences) + stdio-common/Makefile + (usual lay-out differences) + stdio-common/vfscanf-internal.c + (File does not exist downstream. Changes applied to + stdio-common/vfscanf.c.) + +diff -Nrup a/localedata/Makefile b/localedata/Makefile +--- a/localedata/Makefile 2026-06-11 15:40:57.754008211 -0400 ++++ b/localedata/Makefile 2026-06-11 15:41:43.547421657 -0400 +@@ -155,8 +155,8 @@ locale_test_suite := tst_iswalnum tst_is + tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \ + tst-leaks tst-mbswcs1 tst-mbswcs2 tst-mbswcs3 tst-mbswcs4 tst-mbswcs5 \ + tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale tst-bz12701-lc \ +- tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3 \ +- tst-wctype ++ tst-bz12701-lc2 tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 \ ++ tst-setlocale3 tst-wctype + tests-static = bug-setlocale1-static + tests += $(tests-static) + ifeq (yes,$(build-shared)) +diff -Nrup a/localedata/tst-bz12701-lc2.c b/localedata/tst-bz12701-lc2.c +--- a/localedata/tst-bz12701-lc2.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/localedata/tst-bz12701-lc2.c 2026-06-11 15:41:43.547871199 -0400 +@@ -0,0 +1,47 @@ ++/* Verify scanf memory handling with the 'c' conversion (BZ #12701). ++ 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 ++ . */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ wchar_t *c = NULL; ++ int i; ++ ++ TEST_VERIFY (sscanf ("1234", "%30mlc", &c) == 1); ++ ++ TEST_VERIFY (c != NULL); ++ TEST_COMPARE_BLOB (c, 5 * sizeof (wchar_t), ++ L"1234\0", 5 * sizeof (wchar_t)); ++ for (i = 5; i < 30; i ++) ++ TEST_VERIFY (c[i] == L'\0'); ++ ++ TEST_VERIFY (malloc_usable_size (c) >= 30 * sizeof(wchar_t)); ++ ++ return 0; ++} ++ ++#include +diff -Nrup a/stdio-common/Makefile b/stdio-common/Makefile +--- a/stdio-common/Makefile 2026-06-11 15:40:57.754660844 -0400 ++++ b/stdio-common/Makefile 2026-06-11 15:43:00.329832195 -0400 +@@ -49,13 +49,13 @@ tests := tstscanf test_rdwr test-popen t + bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 \ + tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \ + scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \ +- scanf11 scanf12 tst-tmpnam tst-bz12701-c tst-cookie tst-obprintf tst-sscanf \ +- tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \ +- tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 \ +- tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \ +- tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \ +- bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \ +- scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \ ++ scanf11 scanf12 tst-tmpnam tst-bz12701-c tst-bz12701-c2 tst-cookie \ ++ tst-obprintf tst-sscanf tst-swprintf tst-fseek tst-fmemopen \ ++ test-vfprintf tst-gets tst-perror tst-sprintf tst-rndseek tst-fdopen \ ++ tst-fphex bug14 tst-popen tst-unlockedio tst-fmemopen2 tst-put-error \ ++ tst-fgets tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 \ ++ bug18a bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 \ ++ bug22 scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \ + bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \ + bug25 tst-printf-round bug23-2 bug23-3 bug23-4 bug26 tst-fmemopen3 \ + tst-printf-bz18872 tst-vfprintf-width-prec tst-fmemopen4 \ +diff -Nrup a/stdio-common/tst-bz12701-c2.c b/stdio-common/tst-bz12701-c2.c +--- a/stdio-common/tst-bz12701-c2.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/stdio-common/tst-bz12701-c2.c 2026-06-11 15:41:43.548317866 -0400 +@@ -0,0 +1,46 @@ ++/* Verify scanf memory handling with the 'c' conversion (BZ #12701). ++ 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 ++ . */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ char *c = NULL; ++ int i; ++ ++ TEST_VERIFY (sscanf ("1234", "%30mc", &c) == 1); ++ ++ TEST_VERIFY (c != NULL); ++ TEST_COMPARE_BLOB (c, 5, "1234\0", 5); ++ for (i = 5; i < 30; i ++) ++ TEST_VERIFY (c[i] == '\0'); ++ ++ TEST_VERIFY (malloc_usable_size (c) >= 30); ++ ++ return 0; ++} ++ ++#include +diff -Nrup a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c +--- a/stdio-common/vfscanf.c 2026-06-11 15:40:57.740361719 -0400 ++++ b/stdio-common/vfscanf.c 2026-06-12 14:38:32.544596475 -0400 +@@ -731,9 +731,9 @@ _IO_vfscanf_internal (FILE *s, const cha + conv_error (); \ + } while (0) + #ifdef COMPILE_WSCANF +- STRING_ARG (str, char, 100); ++ STRING_ARG (str, char, (width > 0 ? width : 1)); + #else +- STRING_ARG (str, char, (width > 1024 ? 1024 : width)); ++ STRING_ARG (str, char, (width > 0 ? width : 1)); + #endif + + c = inchar (); +@@ -842,6 +842,11 @@ _IO_vfscanf_internal (FILE *s, const cha + + if (!(flags & SUPPRESS)) + { ++ /* If the buffer isn't completely filled, pad it with NULs. */ ++ if (flags & MALLOC) ++ while (width-- > 0) ++ *str++ = '\0'; ++ + if ((flags & MALLOC) && str - *strptr != strsize) + { + char *cp = (char *) realloc (*strptr, str - *strptr); +@@ -859,7 +864,7 @@ _IO_vfscanf_internal (FILE *s, const cha + if (width == -1) + width = 1; + +- STRING_ARG (wstr, wchar_t, (width > 1024 ? 1024 : width)); ++ STRING_ARG (wstr, wchar_t, (width > 0 ? width : 1)); + + c = inchar (); + if (__glibc_unlikely (c == EOF)) +@@ -995,6 +1000,11 @@ _IO_vfscanf_internal (FILE *s, const cha + + if (!(flags & SUPPRESS)) + { ++ /* If the buffer isn't completely filled, pad it with NULs. */ ++ if (flags & MALLOC) ++ while (width-- > 0) ++ *wstr++ = L'\0'; ++ + if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize) + { + wchar_t *cp = (wchar_t *) realloc (*strptr, diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec index 9b984ab..2a58424 100644 --- a/SPECS/glibc.spec +++ b/SPECS/glibc.spec @@ -115,7 +115,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: %{glibcrelease}.37 +Release: %{glibcrelease}.38 # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -1330,6 +1330,10 @@ Patch1095: glibc-RHEL-162891-4.patch Patch1096: glibc-RHEL-168095.patch Patch1097: glibc-RHEL-173358-1.patch Patch1098: glibc-RHEL-173358-2.patch +Patch1099: glibc-RHEL-172700-1.patch +Patch1100: glibc-RHEL-172700-2.patch +Patch1101: glibc-RHEL-172700-3.patch +Patch1102: glibc-RHEL-172700-4.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2991,6 +2995,9 @@ fi %{_libdir}/libpthread_nonshared.a %changelog + * Tue Jun 02 2026 Patsy Griffin - 2.28-251.38 + - CVE-2026-5450: Fix buffer overflow in scanf (RHEL-172700) + * Mon May 11 2026 Arjun Shankar - 2.28-251.37 - Add tests for CVE-2026-4437 and CVE-2026-4438 (RHEL-173358)