Fix ungetc leak and invalid read (RHEL-54447)

Resolves: RHEL-54447
This commit is contained in:
Siddhesh Poyarekar 2024-08-30 11:47:26 -04:00
parent 07b20a236a
commit 8e284fa1e8
11 changed files with 1499 additions and 1 deletions

331
glibc-RHEL-54447-1.patch Normal file
View File

@ -0,0 +1,331 @@
commit 5456af201d4c0a2950200ba756e5f8314ddbbccd
Author: Carlos O'Donell <carlos@redhat.com>
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)

201
glibc-RHEL-54447-10.patch Normal file
View File

@ -0,0 +1,201 @@
commit 9556acd249687ac562deb6309503165d66eb06fa
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
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 <siddhesh@sourceware.org>
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 <string/test-string.h>
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 <string/test-string.h>
/* 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 <assert.h>
#include <fcntl.h>
+#include <limits.h>
#include <locale.h>
#include <obstack.h>
#include <setjmp.h>
@@ -37,6 +38,10 @@
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <paths.h>
+
+#include <support/temp_file.h>
+#include <support/support.h>
#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 <support/test-driver.c>
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 <stdlib.h>
#include <unistd.h>
-
-static int do_test(void);
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
-
+#include <support/support.h>
static jmp_buf b;
@@ -76,3 +72,5 @@ do_test (void)
puts ("second longjmp returned");
return 1;
}
+
+#include <support/test-driver.c>
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 <sys/resource.h>
#include <unistd.h>
-static int do_test (void);
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/support.h>
static jmp_buf mainloop;
static sigset_t mainsigset;
@@ -128,3 +126,5 @@ do_test (void)
return 0;
}
+
+#include <support/test-driver.c>
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 <signal.h>
#include <string.h>
-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 <support/test-driver.c>

195
glibc-RHEL-54447-2.patch Normal file
View File

@ -0,0 +1,195 @@
commit 388c9d7294e5ee3b741aef2e8af63eb1f76ace86
Author: Maciej W. Rozycki <macro@redhat.com>
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/check.h>; '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 <dj@redhat.com>
(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 <stdio.h>
#include <string.h>
+#include <support/check.h>
+
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 <string.h>
#include <tgmath.h>
+#include <support/check.h>
+
//#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(...) \

169
glibc-RHEL-54447-3.patch Normal file
View File

@ -0,0 +1,169 @@
commit 86f5cfe77d60ca4f78f270adc7ae2c15a1d8d4bc
Author: Maciej W. Rozycki <macro@redhat.com>
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 <dj@redhat.com>
(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
+ <https://www.gnu.org/licenses/>. */
+
+#include <error.h>
+#include <errno.h>
+#include <limits.h>
+#include <mcheck.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+
+#include <support/check.h>
+#include <support/test-driver.h>
+
+/* 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 <support/test-driver.c>

143
glibc-RHEL-54447-4.patch Normal file
View File

@ -0,0 +1,143 @@
commit af68f0f6755c3b82ecef6dd67079df64eee8d946
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Wed Aug 14 19:20:04 2024 -0400
Make tst-ungetc use libsupport
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(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
+ <https://www.gnu.org/licenses/>. */
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-
-#undef assert
-#define assert(x) \
- if (!(x)) \
- { \
- fputs ("test failed: " #x "\n", stderr); \
- retval = 1; \
- goto the_end; \
- }
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
-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 <support/test-driver.c>

71
glibc-RHEL-54447-5.patch Normal file
View File

@ -0,0 +1,71 @@
commit 01a731da41a6d47cdd6b90f0da1d89dd8cf2b9cd
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
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 <siddhesh@sourceware.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(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);

136
glibc-RHEL-54447-6.patch Normal file
View File

@ -0,0 +1,136 @@
commit a5cd39541396b91d90cc611858ee7b3355fcfe47
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
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 <siddhesh@sourceware.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(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
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <mcheck.h>
+#include <support/check.h>
+#include <support/support.h>
+
+static int
+do_test (void)
+{
+ mtrace ();
+ TEST_COMPARE (ungetc('y', stdin), 'y');
+ return 0;
+}
+
+#include <support/test-driver.c>

83
glibc-RHEL-54447-7.patch Normal file
View File

@ -0,0 +1,83 @@
commit 9d26e50364def249e483b1601beb6ecf9141ecc7
Author: Maciej W. Rozycki <macro@redhat.com>
Date: Fri Jul 26 13:21:34 2024 +0100
posix: Use <support/check.h> facilities in tst-truncate and tst-truncate64
Remove local FAIL macro in favor to FAIL_RET from <support/check.h>,
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 <dj@redhat.com>
(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 <sys/stat.h>
#include <unistd.h>
+#include <support/check.h>
+
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;
}

129
glibc-RHEL-54447-8.patch Normal file
View File

@ -0,0 +1,129 @@
commit c21ca2a696c03ff3f3931768a3ada234eebf6337
Author: Maciej W. Rozycki <macro@redhat.com>
Date: Fri Jul 26 13:21:34 2024 +0100
nptl: Use <support/check.h> facilities in tst-setuid3
Remove local FAIL macro in favor to FAIL_EXIT1 from <support/check.h>,
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 <dj@redhat.com>
(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
<https://www.gnu.org/licenses/>. */
-#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <stdbool.h>
#include <unistd.h>
+#include <support/check.h>
+
/* 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;
}

27
glibc-RHEL-54447-9.patch Normal file
View File

@ -0,0 +1,27 @@
commit ae4d44b1d501421ad9a3af95279b8f4d1546f1ce
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
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 <siddhesh@sourceware.org>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
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)

View File

@ -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 <siddhesh@redhat.com> - 2.34-124
- Fix ungetc leak and invalid read (RHEL-54447)
* Tue Sep 03 2024 Patsy Griffin <patsy@redhat.com> - 2.34-123
- s390x: Fix segfault in wcsncmp
- Enhanced test coverage for strncmp, wcsncmp (RHEL-49489)