From 8e284fa1e88066a32a9d32fe2263678d11a243fa Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Fri, 30 Aug 2024 11:47:26 -0400 Subject: [PATCH] Fix ungetc leak and invalid read (RHEL-54447) Resolves: RHEL-54447 --- glibc-RHEL-54447-1.patch | 331 ++++++++++++++++++++++++++++++++++++++ glibc-RHEL-54447-10.patch | 201 +++++++++++++++++++++++ glibc-RHEL-54447-2.patch | 195 ++++++++++++++++++++++ glibc-RHEL-54447-3.patch | 169 +++++++++++++++++++ glibc-RHEL-54447-4.patch | 143 ++++++++++++++++ glibc-RHEL-54447-5.patch | 71 ++++++++ glibc-RHEL-54447-6.patch | 136 ++++++++++++++++ glibc-RHEL-54447-7.patch | 83 ++++++++++ glibc-RHEL-54447-8.patch | 129 +++++++++++++++ glibc-RHEL-54447-9.patch | 27 ++++ glibc.spec | 15 +- 11 files changed, 1499 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-54447-1.patch create mode 100644 glibc-RHEL-54447-10.patch create mode 100644 glibc-RHEL-54447-2.patch create mode 100644 glibc-RHEL-54447-3.patch create mode 100644 glibc-RHEL-54447-4.patch create mode 100644 glibc-RHEL-54447-5.patch create mode 100644 glibc-RHEL-54447-6.patch create mode 100644 glibc-RHEL-54447-7.patch create mode 100644 glibc-RHEL-54447-8.patch create mode 100644 glibc-RHEL-54447-9.patch diff --git a/glibc-RHEL-54447-1.patch b/glibc-RHEL-54447-1.patch new file mode 100644 index 0000000..e625815 --- /dev/null +++ b/glibc-RHEL-54447-1.patch @@ -0,0 +1,331 @@ +commit 5456af201d4c0a2950200ba756e5f8314ddbbccd +Author: Carlos O'Donell +Date: Thu May 11 14:00:41 2023 -0400 + + stdio-common: Reformat Makefile. + + Reflow Makefile. + Sort using scripts/sort-makefile-lines.py. + + Code generation is changed as routines are linked in sorted order + as expected. + + No regressions on x86_64 and i686. + + (cherry picked from commit c3004417afc98585089a9282d1d4d60cdef5317a) + (cherry picked from commit 5b4e90230b8147e273585bf296bf1a9fb6e2b4c2) + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 803f16dae030cb72..76d1d0a1193aa109 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -22,82 +22,241 @@ subdir := stdio-common + + include ../Makeconfig + +-headers := stdio_ext.h printf.h bits/printf-ldbl.h bits/stdio_lim.h +- +-routines := \ +- ctermid cuserid \ +- _itoa _itowa itoa-digits itoa-udigits itowa-digits \ +- vfprintf vprintf printf_fp reg-printf printf-prs printf_fphex \ +- reg-modifier reg-type \ +- printf_size fprintf printf snprintf sprintf asprintf dprintf \ +- vfwprintf vfscanf vfwscanf \ +- fscanf scanf sscanf \ +- perror psignal \ +- tmpfile tmpfile64 tmpnam tmpnam_r tempnam tempname \ +- getline getw putw \ +- remove rename renameat renameat2 \ +- flockfile ftrylockfile funlockfile \ +- isoc99_scanf isoc99_vscanf isoc99_fscanf isoc99_vfscanf isoc99_sscanf \ +- isoc99_vsscanf \ +- psiginfo gentempfd \ +- vfscanf-internal vfwscanf-internal iovfscanf \ +- vfprintf-internal vfwprintf-internal +- +-aux := errlist siglist printf-parsemb printf-parsewc fxprintf +- +-tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ +- temptest tst-fileno test-fwrite tst-ungetc tst-ferror \ +- xbug errnobug \ +- 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 \ +- 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 \ +- tst-vfprintf-user-type \ +- tst-vfprintf-mbs-prec \ +- tst-scanf-round \ +- tst-renameat2 tst-bz11319 tst-bz11319-fortify2 \ +- scanf14a scanf16a \ +- tst-printf-bz25691 \ +- tst-vfprintf-width-prec-alloc \ +- tst-printf-fp-free \ +- tst-printf-fp-leak \ +- test-strerr +- +- +-test-srcs = tst-unbputc tst-printf tst-printfsz-islongdouble ++headers := \ ++ bits/printf-ldbl.h \ ++ bits/stdio_lim.h \ ++ printf.h \ ++ stdio_ext.h \ ++ # headers ++ ++routines := \ ++ _itoa \ ++ _itowa \ ++ asprintf \ ++ ctermid \ ++ cuserid \ ++ dprintf \ ++ flockfile \ ++ fprintf \ ++ fscanf \ ++ ftrylockfile \ ++ funlockfile \ ++ gentempfd \ ++ getline \ ++ getw \ ++ iovfscanf \ ++ isoc99_fscanf \ ++ isoc99_scanf \ ++ isoc99_sscanf \ ++ isoc99_vfscanf \ ++ isoc99_vscanf \ ++ isoc99_vsscanf \ ++ itoa-digits \ ++ itoa-udigits \ ++ itowa-digits \ ++ perror \ ++ printf \ ++ printf-prs \ ++ printf_fp \ ++ printf_fphex \ ++ printf_size \ ++ psiginfo \ ++ psignal \ ++ putw \ ++ reg-modifier \ ++ reg-printf \ ++ reg-type \ ++ remove \ ++ rename \ ++ renameat \ ++ renameat2 \ ++ scanf \ ++ snprintf \ ++ sprintf \ ++ sscanf \ ++ tempnam \ ++ tempname \ ++ tmpfile \ ++ tmpfile64 tmpnam \ ++ tmpnam_r \ ++ vfprintf \ ++ vfprintf-internal \ ++ vfscanf \ ++ vfscanf-internal \ ++ vfwprintf \ ++ vfwprintf-internal \ ++ vfwscanf \ ++ vfwscanf-internal \ ++ vprintf \ ++ # routines ++ ++aux := \ ++ errlist \ ++ fxprintf \ ++ printf-parsemb \ ++ printf-parsewc \ ++ siglist \ ++ # aux ++ ++tests := \ ++ bug-vfprintf-nargs \ ++ bug1 \ ++ bug10 \ ++ bug11 \ ++ bug12 \ ++ bug13 \ ++ bug14 \ ++ bug16 \ ++ bug17 \ ++ bug18 \ ++ bug18a \ ++ bug19 \ ++ bug19a \ ++ bug2 \ ++ bug20 \ ++ bug21 \ ++ bug22 \ ++ bug23 \ ++ bug23-2 \ ++ bug23-3 \ ++ bug23-4 \ ++ bug24 \ ++ bug25 \ ++ bug26 \ ++ bug3 \ ++ bug4 \ ++ bug5 \ ++ bug6 \ ++ bug7 \ ++ bug8 \ ++ bug9 \ ++ errnobug \ ++ scanf1 \ ++ scanf10 \ ++ scanf11 \ ++ scanf12 \ ++ scanf13 \ ++ scanf14 \ ++ scanf14a \ ++ scanf15 \ ++ scanf16 \ ++ scanf16a \ ++ scanf17 \ ++ scanf2 \ ++ scanf3 \ ++ scanf4 \ ++ scanf5 \ ++ scanf7 \ ++ scanf8 \ ++ scanf9 \ ++ temptest \ ++ test-fseek \ ++ test-fwrite \ ++ test-popen \ ++ test-strerr \ ++ test-vfprintf \ ++ test_rdwr \ ++ tfformat \ ++ tiformat \ ++ tllformat \ ++ tst-bz11319 \ ++ tst-bz11319-fortify2 \ ++ tst-cookie \ ++ tst-fdopen \ ++ tst-ferror \ ++ tst-fgets \ ++ tst-fileno \ ++ tst-fmemopen \ ++ tst-fmemopen2 \ ++ tst-fmemopen3 \ ++ tst-fmemopen4 \ ++ tst-fphex \ ++ tst-fphex-wide \ ++ tst-fseek \ ++ tst-fwrite \ ++ tst-gets \ ++ tst-grouping \ ++ tst-long-dbl-fphex \ ++ tst-obprintf \ ++ tst-perror \ ++ tst-popen \ ++ tst-popen2 \ ++ tst-printf-bz18872 \ ++ tst-printf-bz25691 \ ++ tst-printf-fp-free \ ++ tst-printf-fp-leak \ ++ tst-printf-round \ ++ tst-printfsz \ ++ tst-put-error \ ++ tst-renameat2 \ ++ tst-rndseek \ ++ tst-scanf-round \ ++ tst-setvbuf1 \ ++ tst-sprintf \ ++ tst-sprintf2 \ ++ tst-sprintf3 \ ++ tst-sscanf \ ++ tst-swprintf \ ++ tst-swscanf \ ++ tst-tmpnam \ ++ tst-ungetc \ ++ tst-unlockedio \ ++ tst-vfprintf-mbs-prec \ ++ tst-vfprintf-user-type \ ++ tst-vfprintf-width-prec \ ++ tst-vfprintf-width-prec-alloc \ ++ tst-wc-printf \ ++ tstdiomisc \ ++ tstgetln \ ++ tstscanf \ ++ xbug \ ++ # tests ++ ++test-srcs = \ ++ tst-printf \ ++ tst-printfsz-islongdouble \ ++ tst-unbputc \ ++ # test-srcs + + ifeq ($(run-built-tests),yes) +-tests-special += $(objpfx)tst-unbputc.out $(objpfx)tst-printf.out \ +- $(objpfx)tst-printf-bz18872-mem.out \ +- $(objpfx)tst-setvbuf1-cmp.out \ +- $(objpfx)tst-vfprintf-width-prec-mem.out \ +- $(objpfx)tst-printfsz-islongdouble.out \ +- $(objpfx)tst-printf-bz25691-mem.out \ +- $(objpfx)tst-printf-fp-free-mem.out \ +- $(objpfx)tst-printf-fp-leak-mem.out +-generated += tst-printf-bz18872.c tst-printf-bz18872.mtrace \ +- tst-printf-bz18872-mem.out \ +- tst-vfprintf-width-prec.mtrace tst-vfprintf-width-prec-mem.out \ +- tst-printf-bz25691.mtrace tst-printf-bz25691-mem.out \ +- tst-printf-fp-free.mtrace tst-printf-fp-free-mem.out \ +- tst-printf-fp-leak.mtrace tst-printf-fp-leak-mem.out +-endif ++tests-special += \ ++ $(objpfx)tst-printf-bz18872-mem.out \ ++ $(objpfx)tst-printf-bz25691-mem.out \ ++ $(objpfx)tst-printf-fp-free-mem.out \ ++ $(objpfx)tst-printf-fp-leak-mem.out \ ++ $(objpfx)tst-printf.out \ ++ $(objpfx)tst-printfsz-islongdouble.out \ ++ $(objpfx)tst-setvbuf1-cmp.out \ ++ $(objpfx)tst-unbputc.out \ ++ $(objpfx)tst-vfprintf-width-prec-mem.out \ ++ # tests-special ++ ++generated += \ ++ tst-printf-bz18872-mem.out \ ++ tst-printf-bz18872.c \ ++ tst-printf-bz18872.mtrace \ ++ tst-printf-bz25691-mem.out \ ++ tst-printf-bz25691.mtrace \ ++ tst-printf-fp-free-mem.out \ ++ tst-printf-fp-free.mtrace \ ++ tst-printf-fp-leak-mem.out \ ++ tst-printf-fp-leak.mtrace \ ++ tst-vfprintf-width-prec-mem.out \ ++ tst-vfprintf-width-prec.mtrace \ ++ # generated ++endif # $(run-built-tests) + + tests-special += $(objpfx)tst-errno-manual.out + + include ../Rules + + ifeq ($(run-built-tests),yes) +-LOCALES := de_DE.ISO-8859-1 de_DE.UTF-8 en_US.ISO-8859-1 ja_JP.EUC-JP ++LOCALES := \ ++ de_DE.ISO-8859-1 \ ++ de_DE.UTF-8 \ ++ en_US.ISO-8859-1 \ ++ ja_JP.EUC-JP \ ++ # LOCALES + include ../gen-locales.mk + + $(objpfx)bug14.out: $(gen-locales) diff --git a/glibc-RHEL-54447-10.patch b/glibc-RHEL-54447-10.patch new file mode 100644 index 0000000..6258b77 --- /dev/null +++ b/glibc-RHEL-54447-10.patch @@ -0,0 +1,201 @@ +commit 9556acd249687ac562deb6309503165d66eb06fa +Author: Adhemerval Zanella +Date: Thu Dec 21 15:59:15 2023 -0300 + + debug: Adapt fortify tests to libsupport + + Checked on aarch64, armhf, x86_64, and i686. + Reviewed-by: Siddhesh Poyarekar + +diff --git a/debug/test-stpcpy_chk.c b/debug/test-stpcpy_chk.c +index 96ad600bc2760cbd..c3cb52d987f9db4f 100644 +--- a/debug/test-stpcpy_chk.c ++++ b/debug/test-stpcpy_chk.c +@@ -20,7 +20,7 @@ + #define STRCPY_RESULT(dst, len) ((dst) + (len)) + #define TEST_MAIN + #define TEST_NAME "stpcpy_chk" +-#include "../string/test-string.h" ++#include + + extern void __attribute__ ((noreturn)) __chk_fail (void); + char *simple_stpcpy_chk (char *, const char *, size_t); +diff --git a/debug/test-strcpy_chk.c b/debug/test-strcpy_chk.c +index 80c07482aaa54e3b..bb89e342caef470b 100644 +--- a/debug/test-strcpy_chk.c ++++ b/debug/test-strcpy_chk.c +@@ -21,7 +21,7 @@ + # define STRCPY_RESULT(dst, len) dst + # define TEST_MAIN + # define TEST_NAME "strcpy_chk" +-# include "../string/test-string.h" ++# include + + /* This test case implicitly tests the availability of the __chk_fail + symbol, which is part of the public ABI and may be used +diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c +index fb02452f5993c594..01a8703de1e6e09a 100644 +--- a/debug/tst-fortify.c ++++ b/debug/tst-fortify.c +@@ -24,6 +24,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -37,6 +38,10 @@ + #include + #include + #include ++#include ++ ++#include ++#include + + #ifndef _GNU_SOURCE + # define MEMPCPY memcpy +@@ -53,15 +58,10 @@ + #define obstack_chunk_alloc malloc + #define obstack_chunk_free free + +-char *temp_filename; +-static void do_prepare (void); +-static int do_test (void); +-#define PREPARE(argc, argv) do_prepare () +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" ++static char *temp_filename; + + static void +-do_prepare (void) ++do_prepare (int argc, char *argv[]) + { + int temp_fd = create_temp_file ("tst-chk1.", &temp_filename); + if (temp_fd == -1) +@@ -78,10 +78,11 @@ do_prepare (void) + exit (1); + } + } ++#define PREPARE do_prepare + +-volatile int chk_fail_ok; +-volatile int ret; +-jmp_buf chk_fail_buf; ++static volatile int chk_fail_ok; ++static volatile int ret; ++static jmp_buf chk_fail_buf; + + static void + handler (int sig) +@@ -103,22 +104,22 @@ wchar_t wbuf[10]; + #define buf_size sizeof (buf) + #endif + +-volatile size_t l0; +-volatile char *p; +-volatile wchar_t *wp; +-const char *str1 = "JIHGFEDCBA"; +-const char *str2 = "F"; +-const char *str3 = "%s%n%s%n"; +-const char *str4 = "Hello, "; +-const char *str5 = "World!\n"; +-const wchar_t *wstr1 = L"JIHGFEDCBA"; +-const wchar_t *wstr2 = L"F"; +-const wchar_t *wstr3 = L"%s%n%s%n"; +-const wchar_t *wstr4 = L"Hello, "; +-const wchar_t *wstr5 = L"World!\n"; +-char buf2[10] = "%s"; +-int num1 = 67; +-int num2 = 987654; ++static volatile size_t l0; ++static volatile char *p; ++static volatile wchar_t *wp; ++static const char *str1 = "JIHGFEDCBA"; ++static const char *str2 = "F"; ++static const char *str3 = "%s%n%s%n"; ++static const char *str4 = "Hello, "; ++static const char *str5 = "World!\n"; ++static const wchar_t *wstr1 = L"JIHGFEDCBA"; ++static const wchar_t *wstr2 = L"F"; ++static const wchar_t *wstr3 = L"%s%n%s%n"; ++static const wchar_t *wstr4 = L"Hello, "; ++static const wchar_t *wstr5 = L"World!\n"; ++static char buf2[10] = "%s"; ++static int num1 = 67; ++static int num2 = 987654; + + #define FAIL() \ + do { printf ("Failure on line %d\n", __LINE__); ret = 1; } while (0) +@@ -1763,3 +1764,5 @@ do_test (void) + + return ret; + } ++ ++#include +diff --git a/debug/tst-longjmp_chk.c b/debug/tst-longjmp_chk.c +index e4e93d2a36b537d9..37f858606be4c4a2 100644 +--- a/debug/tst-longjmp_chk.c ++++ b/debug/tst-longjmp_chk.c +@@ -10,11 +10,7 @@ + #include + #include + +- +-static int do_test(void); +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" +- ++#include + + static jmp_buf b; + +@@ -76,3 +72,5 @@ do_test (void) + puts ("second longjmp returned"); + return 1; + } ++ ++#include +diff --git a/debug/tst-longjmp_chk2.c b/debug/tst-longjmp_chk2.c +index 23d3436d1d26d2d1..69c1ab9db73f14ae 100644 +--- a/debug/tst-longjmp_chk2.c ++++ b/debug/tst-longjmp_chk2.c +@@ -12,9 +12,7 @@ + #include + #include + +-static int do_test (void); +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" ++#include + + static jmp_buf mainloop; + static sigset_t mainsigset; +@@ -128,3 +126,5 @@ do_test (void) + + return 0; + } ++ ++#include +diff --git a/debug/tst-longjmp_chk3.c b/debug/tst-longjmp_chk3.c +index 3155c7769fcbd83f..4434937c597dbe10 100644 +--- a/debug/tst-longjmp_chk3.c ++++ b/debug/tst-longjmp_chk3.c +@@ -20,10 +20,6 @@ + #include + #include + +-static int do_test (void); +-#define TEST_FUNCTION do_test () +-#include "../test-skeleton.c" +- + static char buf[SIGSTKSZ * 4]; + static jmp_buf jb; + +@@ -83,3 +79,5 @@ do_test (void) + puts ("longjmp returned and shouldn't"); + return 1; + } ++ ++#include diff --git a/glibc-RHEL-54447-2.patch b/glibc-RHEL-54447-2.patch new file mode 100644 index 0000000..1c39e95 --- /dev/null +++ b/glibc-RHEL-54447-2.patch @@ -0,0 +1,195 @@ +commit 388c9d7294e5ee3b741aef2e8af63eb1f76ace86 +Author: Maciej W. Rozycki +Date: Fri Jul 26 13:21:34 2024 +0100 + + support: Add FAIL test failure helper + + Add a FAIL test failure helper analogous to FAIL_RET, that does not + cause the current function to return, providing a standardized way to + report a test failure with a message supplied while permitting the + caller to continue executing, for further reporting, cleaning up, etc. + + Update existing test cases that provide a conflicting definition of FAIL + by removing the local FAIL definition and then as follows: + + - tst-fortify-syslog: provide a meaningful message in addition to the + file name already added by ; 'support_record_failure' + is already called by 'support_print_failure_impl' invoked by the new + FAIL test failure helper. + + - tst-ctype: no update to FAIL calls required, with the name of the file + and the line number within of the failure site additionally included + by the new FAIL test failure helper, and error counting plus count + reporting upon test program termination also already provided by + 'support_record_failure' and 'support_report_failure' respectively, + called by 'support_print_failure_impl' and 'adjust_exit_status' also + respectively. However in a number of places 'printf' is called and + the error count adjusted by hand, so update these places to make use + of FAIL instead. And last but not least adjust the final summary just + to report completion, with any error count following as reported by + the test driver. + + - test-tgmath2: no update to FAIL calls required, with the name of the + file of the failure site additionally included by the new FAIL test + failure helper. Also there is no need to track the return status by + hand as any call to FAIL will eventually cause the test case to return + an unsuccesful exit status regardless of the return status from the + test function, via a call to 'adjust_exit_status' made by the test + driver. + + Reviewed-by: DJ Delorie + (cherry picked from commit 1b97a9f23bf605ca608162089c94187573fb2a9e) + (cherry picked from commit 28f358bc4209ab0425170cdccf65bb1fe861148f) + +diff --git a/localedata/tst-ctype.c b/localedata/tst-ctype.c +index 1e4fa132bb4e17c6..f8645e31db8a1691 100644 +--- a/localedata/tst-ctype.c ++++ b/localedata/tst-ctype.c +@@ -22,6 +22,8 @@ + #include + #include + ++#include ++ + + static const char lower[] = "abcdefghijklmnopqrstuvwxyz"; + static const char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +@@ -54,19 +56,11 @@ static struct classes + #define nclasses (sizeof (classes) / sizeof (classes[0])) + + +-#define FAIL(str, args...) \ +- { \ +- printf (" " str "\n", ##args); \ +- ++errors; \ +- } +- +- + static int + do_test (void) + { + const char *cp; + const char *cp2; +- int errors = 0; + char *inpline = NULL; + size_t inplinelen = 0; + char *resline = NULL; +@@ -395,11 +389,8 @@ punct = %04x alnum = %04x\n", + { + if (((__ctype_b[(unsigned int) *inp] & classes[n].mask) != 0) + != (*resp != '0')) +- { +- printf (" is%s('%c' = '\\x%02x') %s true\n", inpline, +- *inp, *inp, *resp == '1' ? "not" : "is"); +- ++errors; +- } ++ FAIL (" is%s('%c' = '\\x%02x') %s true\n", inpline, ++ *inp, *inp, *resp == '1' ? "not" : "is"); + ++inp; + ++resp; + } +@@ -409,11 +400,8 @@ punct = %04x alnum = %04x\n", + while (*inp != '\0') + { + if (tolower (*inp) != *resp) +- { +- printf (" tolower('%c' = '\\x%02x') != '%c'\n", +- *inp, *inp, *resp); +- ++errors; +- } ++ FAIL (" tolower('%c' = '\\x%02x') != '%c'\n", ++ *inp, *inp, *resp); + ++inp; + ++resp; + } +@@ -423,11 +411,8 @@ punct = %04x alnum = %04x\n", + while (*inp != '\0') + { + if (toupper (*inp) != *resp) +- { +- printf (" toupper('%c' = '\\x%02x') != '%c'\n", +- *inp, *inp, *resp); +- ++errors; +- } ++ FAIL (" toupper('%c' = '\\x%02x') != '%c'\n", ++ *inp, *inp, *resp); + ++inp; + ++resp; + } +@@ -437,14 +422,7 @@ punct = %04x alnum = %04x\n", + } + + +- if (errors != 0) +- { +- printf (" %d error%s for `%s' locale\n\n\n", errors, +- errors == 1 ? "" : "s", setlocale (LC_ALL, NULL)); +- return 1; +- } +- +- printf (" No errors for `%s' locale\n\n\n", setlocale (LC_ALL, NULL)); ++ printf ("Completed testing for `%s' locale\n\n\n", setlocale (LC_ALL, NULL)); + return 0; + } + +diff --git a/math/test-tgmath2.c b/math/test-tgmath2.c +index b8fb00c566439ab0..e3b7a3a3615e083a 100644 +--- a/math/test-tgmath2.c ++++ b/math/test-tgmath2.c +@@ -25,6 +25,8 @@ + #include + #include + ++#include ++ + //#define DEBUG + + typedef complex float cfloat; +@@ -88,13 +90,6 @@ enum + int count; + int counts[Tlast][C_last]; + +-#define FAIL(str) \ +- do \ +- { \ +- printf ("%s failure on line %d\n", (str), __LINE__); \ +- result = 1; \ +- } \ +- while (0) + #define TEST_TYPE_ONLY(expr, rettype) \ + do \ + { \ +@@ -134,8 +129,6 @@ int counts[Tlast][C_last]; + int + test_cos (const int Vint4, const long long int Vllong4) + { +- int result = 0; +- + TEST (cos (vfloat1), float, cos); + TEST (cos (vdouble1), double, cos); + TEST (cos (vldouble1), ldouble, cos); +@@ -153,7 +146,7 @@ test_cos (const int Vint4, const long long int Vllong4) + TEST (cos (Vcdouble1), cdouble, cos); + TEST (cos (Vcldouble1), cldouble, cos); + +- return result; ++ return 0; + } + + int +diff --git a/support/check.h b/support/check.h +index 9b1844352f32513a..8e045dd9c0c36b4c 100644 +--- a/support/check.h ++++ b/support/check.h +@@ -24,6 +24,11 @@ + + __BEGIN_DECLS + ++/* Record a test failure, print the failure message to standard output ++ and pass the result of 1 through. */ ++#define FAIL(...) \ ++ support_print_failure_impl (__FILE__, __LINE__, __VA_ARGS__) ++ + /* Record a test failure, print the failure message to standard output + and return 1. */ + #define FAIL_RET(...) \ diff --git a/glibc-RHEL-54447-3.patch b/glibc-RHEL-54447-3.patch new file mode 100644 index 0000000..a7b2bdd --- /dev/null +++ b/glibc-RHEL-54447-3.patch @@ -0,0 +1,169 @@ +commit 86f5cfe77d60ca4f78f270adc7ae2c15a1d8d4bc +Author: Maciej W. Rozycki +Date: Fri Jul 26 13:21:34 2024 +0100 + + stdio-common: Add test for vfscanf with matches longer than INT_MAX [BZ #27650] + + Complement commit b03e4d7bd25b ("stdio: fix vfscanf with matches longer + than INT_MAX (bug 27650)") and add a test case for the issue, inspired + by the reproducer provided with the bug report. + + This has been verified to succeed as from the commit referred and fail + beforehand. + + As the test requires 2GiB of data to be passed around its performance + has been evaluated using a choice of systems and the execution time + determined to be respectively in the range of 9s for POWER9@2.166GHz, + 24s for FU740@1.2GHz, and 40s for 74Kf@950MHz. As this is on the verge + of and beyond the default timeout it has been increased by the factor of + 8. Regardless, following recent practice the test has been added to the + standard rather than extended set. + + Reviewed-by: DJ Delorie + (cherry picked from commit 89cddc8a7096f3d9225868304d2bc0a1aaf07d63) + (cherry picked from commit 99ffa84bdcdc3d81e82f448279f0c8278dd30964) + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 76d1d0a1193aa109..08bedd01be61a55d 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -190,6 +190,7 @@ tests := \ + tst-put-error \ + tst-renameat2 \ + tst-rndseek \ ++ tst-scanf-bz27650 \ + tst-scanf-round \ + tst-setvbuf1 \ + tst-sprintf \ +@@ -241,6 +242,7 @@ generated += \ + tst-printf-fp-free.mtrace \ + tst-printf-fp-leak-mem.out \ + tst-printf-fp-leak.mtrace \ ++ tst-scanf-bz27650.mtrace \ + tst-vfprintf-width-prec-mem.out \ + tst-vfprintf-width-prec.mtrace \ + # generated +@@ -283,6 +285,9 @@ tst-printf-fp-free-ENV = \ + tst-printf-fp-leak-ENV = \ + MALLOC_TRACE=$(objpfx)tst-printf-fp-leak.mtrace \ + LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so ++tst-scanf-bz27650-ENV = \ ++ MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \ ++ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so + + $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc + $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \ +diff --git a/stdio-common/tst-scanf-bz27650.c b/stdio-common/tst-scanf-bz27650.c +new file mode 100644 +index 0000000000000000..3a742bc86556908c +--- /dev/null ++++ b/stdio-common/tst-scanf-bz27650.c +@@ -0,0 +1,108 @@ ++/* Test for BZ #27650, formatted input matching beyond INT_MAX. ++ 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++/* Produce a stream of more than INT_MAX characters via buffer BUF of ++ size SIZE according to bookkeeping in COOKIE and then return EOF. */ ++ ++static ssize_t ++io_read (void *cookie, char *buf, size_t size) ++{ ++ unsigned int *written = cookie; ++ unsigned int w = *written; ++ ++ if (w > INT_MAX) ++ return 0; ++ ++ memset (buf, 'a', size); ++ *written = w + size; ++ return size; ++} ++ ++/* Consume a stream of more than INT_MAX characters from an artificial ++ input stream of which none is the new line character. The call to ++ fscanf is supposed to complete upon the EOF condition of input, ++ however in the presence of BZ #27650 it will terminate prematurely ++ with characters still outstanding in input. Diagnose the condition ++ and return status accordingly. */ ++ ++int ++do_test (void) ++{ ++ static cookie_io_functions_t io_funcs = { .read = io_read }; ++ unsigned int written = 0; ++ FILE *in; ++ int v; ++ ++ mtrace (); ++ ++ in = fopencookie (&written, "r", io_funcs); ++ if (in == NULL) ++ { ++ FAIL ("fopencookie: %m"); ++ goto out; ++ } ++ ++ v = fscanf (in, "%*[^\n]"); ++ if (ferror (in)) ++ { ++ FAIL ("fscanf: input failure, at %u: %m", written); ++ goto out_close; ++ } ++ else if (v == EOF) ++ { ++ FAIL ("fscanf: unexpected end of file, at %u", written); ++ goto out_close; ++ } ++ ++ if (!feof (in)) ++ { ++ v = fgetc (in); ++ if (ferror (in)) ++ FAIL ("fgetc: input failure: %m"); ++ else if (v == EOF) ++ FAIL ("fgetc: unexpected end of file after missing end of file"); ++ else if (v == '\n') ++ FAIL ("unexpected new line character received"); ++ else ++ FAIL ("character received after end of file expected: \\x%02x", v); ++ } ++ ++out_close: ++ if (fclose (in) != 0) ++ FAIL ("fclose: %m"); ++ ++out: ++ return EXIT_SUCCESS; ++} ++ ++#define TIMEOUT (DEFAULT_TIMEOUT * 8) ++#include diff --git a/glibc-RHEL-54447-4.patch b/glibc-RHEL-54447-4.patch new file mode 100644 index 0000000..525ce22 --- /dev/null +++ b/glibc-RHEL-54447-4.patch @@ -0,0 +1,143 @@ +commit af68f0f6755c3b82ecef6dd67079df64eee8d946 +Author: Siddhesh Poyarekar +Date: Wed Aug 14 19:20:04 2024 -0400 + + Make tst-ungetc use libsupport + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Carlos O'Donell + (cherry picked from commit 3f7df7e757f4efec38e45d4068e5492efcac4856) + (cherry picked from commit 87a1968a72e4b4e5436f3e2be1ed8a8d5a5862c7) + +diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c +index 1344b2b591e3d6b1..5c808f073419f00b 100644 +--- a/stdio-common/tst-ungetc.c ++++ b/stdio-common/tst-ungetc.c +@@ -1,70 +1,72 @@ +-/* Test for ungetc bugs. */ ++/* Test for ungetc bugs. ++ Copyright (C) 1996-2024 Free Software Foundation, Inc. ++ Copyright 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 + #include +-#include +- +-#undef assert +-#define assert(x) \ +- if (!(x)) \ +- { \ +- fputs ("test failed: " #x "\n", stderr); \ +- retval = 1; \ +- goto the_end; \ +- } ++#include ++#include ++#include ++#include ++#include + +-int +-main (int argc, char *argv[]) ++static int ++do_test (void) + { +- char name[] = "/tmp/tst-ungetc.XXXXXX"; ++ char *name = NULL; + FILE *fp = NULL; +- int retval = 0; + int c; + char buffer[64]; + +- int fd = mkstemp (name); ++ int fd = create_temp_file ("tst-ungetc.", &name); + if (fd == -1) +- { +- printf ("mkstemp failed: %m\n"); +- return 1; +- } +- close (fd); +- fp = fopen (name, "w"); +- assert (fp != NULL) +- fputs ("bla", fp); +- fclose (fp); +- fp = NULL; ++ FAIL_EXIT1 ("cannot create temporary file: %m"); ++ xclose (fd); + +- fp = fopen (name, "r"); +- assert (fp != NULL); +- assert (ungetc ('z', fp) == 'z'); +- assert (getc (fp) == 'z'); +- assert (getc (fp) == 'b'); +- assert (getc (fp) == 'l'); +- assert (ungetc ('m', fp) == 'm'); +- assert (getc (fp) == 'm'); +- assert ((c = getc (fp)) == 'a'); +- assert (getc (fp) == EOF); +- assert (ungetc (c, fp) == c); +- assert (feof (fp) == 0); +- assert (getc (fp) == c); +- assert (getc (fp) == EOF); +- fclose (fp); +- fp = NULL; ++ fp = xfopen (name, "w"); ++ fputs ("bla", fp); ++ xfclose (fp); + +- fp = fopen (name, "r"); +- assert (fp != NULL); +- assert (getc (fp) == 'b'); +- assert (getc (fp) == 'l'); +- assert (ungetc ('b', fp) == 'b'); +- assert (fread (buffer, 1, 64, fp) == 2); +- assert (buffer[0] == 'b'); +- assert (buffer[1] == 'a'); ++ fp = xfopen (name, "r"); ++ TEST_VERIFY_EXIT (ungetc ('z', fp) == 'z'); ++ TEST_VERIFY_EXIT (getc (fp) == 'z'); ++ TEST_VERIFY_EXIT (getc (fp) == 'b'); ++ TEST_VERIFY_EXIT (getc (fp) == 'l'); ++ TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm'); ++ TEST_VERIFY_EXIT (getc (fp) == 'm'); ++ TEST_VERIFY_EXIT ((c = getc (fp)) == 'a'); ++ TEST_VERIFY_EXIT (getc (fp) == EOF); ++ TEST_VERIFY_EXIT (ungetc (c, fp) == c); ++ TEST_VERIFY_EXIT (feof (fp) == 0); ++ TEST_VERIFY_EXIT (getc (fp) == c); ++ TEST_VERIFY_EXIT (getc (fp) == EOF); ++ xfclose (fp); + +-the_end: +- if (fp != NULL) +- fclose (fp); +- unlink (name); ++ fp = xfopen (name, "r"); ++ TEST_VERIFY_EXIT (getc (fp) == 'b'); ++ TEST_VERIFY_EXIT (getc (fp) == 'l'); ++ TEST_VERIFY_EXIT (ungetc ('b', fp) == 'b'); ++ TEST_VERIFY_EXIT (fread (buffer, 1, 64, fp) == 2); ++ TEST_VERIFY_EXIT (buffer[0] == 'b'); ++ TEST_VERIFY_EXIT (buffer[1] == 'a'); ++ xfclose (fp); + +- return retval; ++ return 0; + } ++ ++#include diff --git a/glibc-RHEL-54447-5.patch b/glibc-RHEL-54447-5.patch new file mode 100644 index 0000000..d2d72aa --- /dev/null +++ b/glibc-RHEL-54447-5.patch @@ -0,0 +1,71 @@ +commit 01a731da41a6d47cdd6b90f0da1d89dd8cf2b9cd +Author: Siddhesh Poyarekar +Date: Tue Aug 13 21:00:06 2024 -0400 + + ungetc: Fix uninitialized read when putting into unused streams [BZ #27821] + + When ungetc is called on an unused stream, the backup buffer is + allocated without the main get area being present. This results in + every subsequent ungetc (as the stream remains in the backup area) + checking uninitialized memory in the backup buffer when trying to put a + character back into the stream. + + Avoid comparing the input character with buffer contents when in backup + to avoid this uninitialized read. The uninitialized read is harmless in + this context since the location is promptly overwritten with the input + character, thus fulfilling ungetc functionality. + + Also adjust wording in the manual to drop the paragraph that says glibc + cannot do multiple ungetc back to back since with this change, ungetc + can actually do this. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Carlos O'Donell + (cherry picked from commit cdf0f88f97b0aaceb894cc02b21159d148d7065c) + (cherry picked from commit 804d3c8db79db204154dcf5e11a76f14fdddc570) + +diff --git a/libio/genops.c b/libio/genops.c +index fa509f6219abaf23..a5dd6a06d9e259d8 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -635,7 +635,7 @@ _IO_sputbackc (FILE *fp, int c) + { + int result; + +- if (fp->_IO_read_ptr > fp->_IO_read_base ++ if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp) + && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c) + { + fp->_IO_read_ptr--; +diff --git a/manual/stdio.texi b/manual/stdio.texi +index d3d855fc62b8768b..60ab7e7a5d505bb6 100644 +--- a/manual/stdio.texi ++++ b/manual/stdio.texi +@@ -1467,11 +1467,9 @@ program; usually @code{ungetc} is used only to unread a character that + was just read from the same stream. @Theglibc{} supports this + even on files opened in binary mode, but other systems might not. + +-@Theglibc{} only supports one character of pushback---in other +-words, it does not work to call @code{ungetc} twice without doing input +-in between. Other systems might let you push back multiple characters; +-then reading from the stream retrieves the characters in the reverse +-order that they were pushed. ++@Theglibc{} supports pushing back multiple characters; subsequently ++reading from the stream retrieves the characters in the reverse order ++that they were pushed. + + Pushing back characters doesn't alter the file; only the internal + buffering for the stream is affected. If a file positioning function +diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c +index 5c808f073419f00b..388b202493ddd586 100644 +--- a/stdio-common/tst-ungetc.c ++++ b/stdio-common/tst-ungetc.c +@@ -48,6 +48,8 @@ do_test (void) + TEST_VERIFY_EXIT (getc (fp) == 'b'); + TEST_VERIFY_EXIT (getc (fp) == 'l'); + TEST_VERIFY_EXIT (ungetc ('m', fp) == 'm'); ++ TEST_VERIFY_EXIT (ungetc ('n', fp) == 'n'); ++ TEST_VERIFY_EXIT (getc (fp) == 'n'); + TEST_VERIFY_EXIT (getc (fp) == 'm'); + TEST_VERIFY_EXIT ((c = getc (fp)) == 'a'); + TEST_VERIFY_EXIT (getc (fp) == EOF); diff --git a/glibc-RHEL-54447-6.patch b/glibc-RHEL-54447-6.patch new file mode 100644 index 0000000..006e312 --- /dev/null +++ b/glibc-RHEL-54447-6.patch @@ -0,0 +1,136 @@ +commit a5cd39541396b91d90cc611858ee7b3355fcfe47 +Author: Siddhesh Poyarekar +Date: Tue Aug 13 21:08:49 2024 -0400 + + ungetc: Fix backup buffer leak on program exit [BZ #27821] + + If a file descriptor is left unclosed and is cleaned up by _IO_cleanup + on exit, its backup buffer remains unfreed, registering as a leak in + valgrind. This is not strictly an issue since (1) the program should + ideally be closing the stream once it's not in use and (2) the program + is about to exit anyway, so keeping the backup buffer around a wee bit + longer isn't a real problem. Free it anyway to keep valgrind happy + when the streams in question are the standard ones, i.e. stdout, stdin + or stderr. + + Also, the _IO_have_backup macro checks for _IO_save_base, + which is a roundabout way to check for a backup buffer instead of + directly looking for _IO_backup_base. The roundabout check breaks when + the main get area has not been used and user pushes a char into the + backup buffer with ungetc. Fix this to use the _IO_backup_base + directly. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Carlos O'Donell + (cherry picked from commit 3e1d8d1d1dca24ae90df2ea826a8916896fc7e77) + (cherry picked from commit b9f72bd5de931eac39219018c2fa319a449bb2cf) + +diff --git a/libio/genops.c b/libio/genops.c +index a5dd6a06d9e259d8..b5fc53fd1ef6e911 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -796,6 +796,12 @@ _IO_unbuffer_all (void) + legacy = 1; + #endif + ++ /* Free up the backup area if it was ever allocated. */ ++ if (_IO_have_backup (fp)) ++ _IO_free_backup_area (fp); ++ if (fp->_mode > 0 && _IO_have_wbackup (fp)) ++ _IO_free_wbackup_area (fp); ++ + if (! (fp->_flags & _IO_UNBUFFERED) + /* Iff stream is un-orientated, it wasn't used. */ + && (legacy || fp->_mode != 0)) +diff --git a/libio/libioP.h b/libio/libioP.h +index dc9a2ce9c8d7744c..bab5f3770f0760c4 100644 +--- a/libio/libioP.h ++++ b/libio/libioP.h +@@ -529,8 +529,8 @@ extern void _IO_old_init (FILE *fp, int flags) __THROW; + ((__fp)->_wide_data->_IO_write_base \ + = (__fp)->_wide_data->_IO_write_ptr = __p, \ + (__fp)->_wide_data->_IO_write_end = (__ep)) +-#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL) +-#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_save_base != NULL) ++#define _IO_have_backup(fp) ((fp)->_IO_backup_base != NULL) ++#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_backup_base != NULL) + #define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP) + #define _IO_have_markers(fp) ((fp)->_markers != NULL) + #define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base) +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 08bedd01be61a55d..f10bf28878e0aebc 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -201,6 +201,7 @@ tests := \ + tst-swscanf \ + tst-tmpnam \ + tst-ungetc \ ++ tst-ungetc-leak \ + tst-unlockedio \ + tst-vfprintf-mbs-prec \ + tst-vfprintf-user-type \ +@@ -229,6 +230,7 @@ tests-special += \ + $(objpfx)tst-printfsz-islongdouble.out \ + $(objpfx)tst-setvbuf1-cmp.out \ + $(objpfx)tst-unbputc.out \ ++ $(objpfx)tst-ungetc-leak-mem.out \ + $(objpfx)tst-vfprintf-width-prec-mem.out \ + # tests-special + +@@ -243,6 +245,8 @@ generated += \ + tst-printf-fp-leak-mem.out \ + tst-printf-fp-leak.mtrace \ + tst-scanf-bz27650.mtrace \ ++ tst-ungetc-leak-mem.out \ ++ tst-ungetc-leak.mtrace \ + tst-vfprintf-width-prec-mem.out \ + tst-vfprintf-width-prec.mtrace \ + # generated +@@ -288,6 +292,9 @@ tst-printf-fp-leak-ENV = \ + tst-scanf-bz27650-ENV = \ + MALLOC_TRACE=$(objpfx)tst-scanf-bz27650.mtrace \ + LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so ++tst-ungetc-leak-ENV = \ ++ MALLOC_TRACE=$(objpfx)tst-ungetc-leak.mtrace \ ++ LD_PRELOAD=$(common-objpfx)malloc/libc_malloc_debug.so + + $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc + $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \ +diff --git a/stdio-common/tst-ungetc-leak.c b/stdio-common/tst-ungetc-leak.c +new file mode 100644 +index 0000000000000000..6c5152b43f80b217 +--- /dev/null ++++ b/stdio-common/tst-ungetc-leak.c +@@ -0,0 +1,32 @@ ++/* Test for memory leak with ungetc when stream is unused. ++ Copyright 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 ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ mtrace (); ++ TEST_COMPARE (ungetc('y', stdin), 'y'); ++ return 0; ++} ++ ++#include diff --git a/glibc-RHEL-54447-7.patch b/glibc-RHEL-54447-7.patch new file mode 100644 index 0000000..9446d2a --- /dev/null +++ b/glibc-RHEL-54447-7.patch @@ -0,0 +1,83 @@ +commit 9d26e50364def249e483b1601beb6ecf9141ecc7 +Author: Maciej W. Rozycki +Date: Fri Jul 26 13:21:34 2024 +0100 + + posix: Use facilities in tst-truncate and tst-truncate64 + + Remove local FAIL macro in favor to FAIL_RET from , + which provides equivalent reporting, with the name of the file of the + failure site additionally included, for the tst-truncate-common core + shared between the tst-truncate and tst-truncate64 tests. + + Reviewed-by: DJ Delorie + (cherry picked from commit fe47595504a55e7bb992f8928533df154b510383) + +diff --git a/posix/tst-truncate-common.c b/posix/tst-truncate-common.c +index 00c999d372693bfa..1f6c4bd256a638f9 100644 +--- a/posix/tst-truncate-common.c ++++ b/posix/tst-truncate-common.c +@@ -21,6 +21,8 @@ + #include + #include + ++#include ++ + static void do_prepare (void); + #define PREPARE(argc, argv) do_prepare () + static int do_test (void); +@@ -42,9 +44,6 @@ do_prepare (void) + } + } + +-#define FAIL(str) \ +- do { printf ("error: %s (line %d)\n", str, __LINE__); return 1; } while (0) +- + static int + do_test_with_offset (off_t offset) + { +@@ -54,35 +53,35 @@ do_test_with_offset (off_t offset) + memset (buf, 0xcf, sizeof (buf)); + + if (pwrite (temp_fd, buf, sizeof (buf), offset) != sizeof (buf)) +- FAIL ("write failed"); ++ FAIL_RET ("write failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + sizeof (buf))) +- FAIL ("initial size wrong"); ++ FAIL_RET ("initial size wrong"); + + if (ftruncate (temp_fd, offset + 800) < 0) +- FAIL ("size reduction with ftruncate failed"); ++ FAIL_RET ("size reduction with ftruncate failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800)) +- FAIL ("size after reduction with ftruncate is incorrect"); ++ FAIL_RET ("size after reduction with ftruncate is incorrect"); + + /* The following test covers more than POSIX. POSIX does not require + that ftruncate() can increase the file size. But we are testing + Unix systems. */ + if (ftruncate (temp_fd, offset + 1200) < 0) +- FAIL ("size increate with ftruncate failed"); ++ FAIL_RET ("size increate with ftruncate failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200)) +- FAIL ("size after increase is incorrect"); ++ FAIL_RET ("size after increase is incorrect"); + + if (truncate (temp_filename, offset + 800) < 0) +- FAIL ("size reduction with truncate failed"); ++ FAIL_RET ("size reduction with truncate failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 800)) +- FAIL ("size after reduction with truncate incorrect"); ++ FAIL_RET ("size after reduction with truncate incorrect"); + + /* The following test covers more than POSIX. POSIX does not require + that truncate() can increase the file size. But we are testing + Unix systems. */ + if (truncate (temp_filename, (offset + 1200)) < 0) +- FAIL ("size increase with truncate failed"); ++ FAIL_RET ("size increase with truncate failed"); + if (fstat (temp_fd, &st) < 0 || st.st_size != (offset + 1200)) +- FAIL ("size increase with truncate is incorrect"); ++ FAIL_RET ("size increase with truncate is incorrect"); + + return 0; + } diff --git a/glibc-RHEL-54447-8.patch b/glibc-RHEL-54447-8.patch new file mode 100644 index 0000000..b4e804f --- /dev/null +++ b/glibc-RHEL-54447-8.patch @@ -0,0 +1,129 @@ +commit c21ca2a696c03ff3f3931768a3ada234eebf6337 +Author: Maciej W. Rozycki +Date: Fri Jul 26 13:21:34 2024 +0100 + + nptl: Use facilities in tst-setuid3 + + Remove local FAIL macro in favor to FAIL_EXIT1 from , + which provides equivalent reporting, with the name of the file and the + line number within of the failure site additionally included. Remove + FAIL_ERR altogether and include ": %m" explicitly with the format string + supplied to FAIL_EXIT1 as there seems little value to have a separate + macro just for this. + + Reviewed-by: DJ Delorie + (cherry picked from commit 8c98195af6e6f1ce21743fc26c723e0f7e45bcf2) + +diff --git a/sysdeps/pthread/tst-setuid3.c b/sysdeps/pthread/tst-setuid3.c +index 254555960e1ffe74..88a2a3ef20e273f7 100644 +--- a/sysdeps/pthread/tst-setuid3.c ++++ b/sysdeps/pthread/tst-setuid3.c +@@ -15,24 +15,19 @@ + License along with the GNU C Library; if not, see + . */ + +-#include + #include + #include + #include + #include + ++#include ++ + /* The test must run under a non-privileged user ID. */ + static const uid_t test_uid = 1; + + static pthread_barrier_t barrier1; + static pthread_barrier_t barrier2; + +-#define FAIL(fmt, ...) \ +- do { printf ("FAIL: " fmt "\n", __VA_ARGS__); _exit (1); } while (0) +- +-#define FAIL_ERR(fmt, ...) \ +- do { printf ("FAIL: " fmt ": %m\n", __VA_ARGS__); _exit (1); } while (0) +- + /* True if x is not a successful return code from pthread_barrier_wait. */ + static inline bool + is_invalid_barrier_ret (int x) +@@ -45,10 +40,10 @@ thread_func (void *ctx __attribute__ ((unused))) + { + int ret = pthread_barrier_wait (&barrier1); + if (is_invalid_barrier_ret (ret)) +- FAIL ("pthread_barrier_wait (barrier1) (on thread): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_wait (barrier1) (on thread): %d", ret); + ret = pthread_barrier_wait (&barrier2); + if (is_invalid_barrier_ret (ret)) +- FAIL ("pthread_barrier_wait (barrier2) (on thread): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_wait (barrier2) (on thread): %d", ret); + return NULL; + } + +@@ -59,13 +54,13 @@ setuid_failure (int phase) + switch (ret) + { + case 0: +- FAIL ("setuid succeeded unexpectedly in phase %d", phase); ++ FAIL_EXIT1 ("setuid succeeded unexpectedly in phase %d", phase); + case -1: + if (errno != EPERM) +- FAIL_ERR ("setuid phase %d", phase); ++ FAIL_EXIT1 ("setuid phase %d: %m", phase); + break; + default: +- FAIL ("invalid setuid return value in phase %d: %d", phase, ret); ++ FAIL_EXIT1 ("invalid setuid return value in phase %d: %d", phase, ret); + } + } + +@@ -74,42 +69,42 @@ do_test (void) + { + if (getuid () == 0) + if (setuid (test_uid) != 0) +- FAIL_ERR ("setuid (%u)", (unsigned) test_uid); ++ FAIL_EXIT1 ("setuid (%u): %m", (unsigned) test_uid); + if (setuid (getuid ())) +- FAIL_ERR ("setuid (%s)", "getuid ()"); ++ FAIL_EXIT1 ("setuid (%s): %m", "getuid ()"); + setuid_failure (1); + + int ret = pthread_barrier_init (&barrier1, NULL, 2); + if (ret != 0) +- FAIL ("pthread_barrier_init (barrier1): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_init (barrier1): %d", ret); + ret = pthread_barrier_init (&barrier2, NULL, 2); + if (ret != 0) +- FAIL ("pthread_barrier_init (barrier2): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_init (barrier2): %d", ret); + + pthread_t thread; + ret = pthread_create (&thread, NULL, thread_func, NULL); + if (ret != 0) +- FAIL ("pthread_create: %d", ret); ++ FAIL_EXIT1 ("pthread_create: %d", ret); + + /* Ensure that the thread is running properly. */ + ret = pthread_barrier_wait (&barrier1); + if (is_invalid_barrier_ret (ret)) +- FAIL ("pthread_barrier_wait (barrier1): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_wait (barrier1): %d", ret); + + setuid_failure (2); + + /* Check success case. */ + if (setuid (getuid ()) != 0) +- FAIL_ERR ("setuid (%s)", "getuid ()"); ++ FAIL_EXIT1 ("setuid (%s): %m", "getuid ()"); + + /* Shutdown. */ + ret = pthread_barrier_wait (&barrier2); + if (is_invalid_barrier_ret (ret)) +- FAIL ("pthread_barrier_wait (barrier2): %d", ret); ++ FAIL_EXIT1 ("pthread_barrier_wait (barrier2): %d", ret); + + ret = pthread_join (thread, NULL); + if (ret != 0) +- FAIL ("pthread_join: %d", ret); ++ FAIL_EXIT1 ("pthread_join: %d", ret); + + return 0; + } diff --git a/glibc-RHEL-54447-9.patch b/glibc-RHEL-54447-9.patch new file mode 100644 index 0000000..18e63df --- /dev/null +++ b/glibc-RHEL-54447-9.patch @@ -0,0 +1,27 @@ +commit ae4d44b1d501421ad9a3af95279b8f4d1546f1ce +Author: Siddhesh Poyarekar +Date: Tue Sep 3 14:58:33 2024 -0400 + + libio: Attempt wide backup free only for non-legacy code + + _wide_data and _mode are not available in legacy code, so do not attempt + to free the wide backup buffer in legacy code. + + Resolves: BZ #32137 and BZ #27821 + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Florian Weimer + +diff --git a/libio/genops.c b/libio/genops.c +index b5fc53fd1ef6e911..99ef9d03505f3238 100644 +--- a/libio/genops.c ++++ b/libio/genops.c +@@ -799,7 +799,7 @@ _IO_unbuffer_all (void) + /* Free up the backup area if it was ever allocated. */ + if (_IO_have_backup (fp)) + _IO_free_backup_area (fp); +- if (fp->_mode > 0 && _IO_have_wbackup (fp)) ++ if (!legacy && fp->_mode > 0 && _IO_have_wbackup (fp)) + _IO_free_wbackup_area (fp); + + if (! (fp->_flags & _IO_UNBUFFERED) diff --git a/glibc.spec b/glibc.spec index ee337d9..75c43e2 100644 --- a/glibc.spec +++ b/glibc.spec @@ -157,7 +157,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 123%{?dist} +Release: 124%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -855,6 +855,16 @@ Patch616: glibc-RHEL-36148-2.patch Patch617: glibc-RHEL-36148-3.patch Patch618: glibc-RHEL-49489-1.patch Patch619: glibc-RHEL-49489-2.patch +Patch620: glibc-RHEL-54447-1.patch +Patch621: glibc-RHEL-54447-2.patch +Patch622: glibc-RHEL-54447-3.patch +Patch623: glibc-RHEL-54447-4.patch +Patch624: glibc-RHEL-54447-5.patch +Patch625: glibc-RHEL-54447-6.patch +Patch626: glibc-RHEL-54447-7.patch +Patch627: glibc-RHEL-54447-8.patch +Patch628: glibc-RHEL-54447-9.patch +Patch629: glibc-RHEL-54447-10.patch ############################################################################## # Continued list of core "glibc" package information: @@ -3014,6 +3024,9 @@ update_gconv_modules_cache () %endif %changelog +* Thu Sep 5 2024 Siddhesh Poyarekar - 2.34-124 +- Fix ungetc leak and invalid read (RHEL-54447) + * Tue Sep 03 2024 Patsy Griffin - 2.34-123 - s390x: Fix segfault in wcsncmp - Enhanced test coverage for strncmp, wcsncmp (RHEL-49489)