sync from glibc upstream branch 2.38
-nptl: Use <support/check.h> facilities in tst-setuid3 - posix: Use <support/check.h> facilities in tst-truncate and tst-truncate64 - ungetc: Fix backup buffer leak on program exit [BZ #27821] - ungetc: Fix uninitialized read when putting into unused streams [BZ #27821] - Make tst-ungetc use libsupport - stdio-common: Add test for vfscanf with matches longer than INT_MAX [BZ #27650] - support: Add FAIL test failure helper (cherry picked from commit 7b1f3d1a6f77908bbb340b0657f1a6fd37288d44)
This commit is contained in:
parent
5aab473e42
commit
d925c00e19
147
Make-tst-ungetc-use-libsupport.patch
Normal file
147
Make-tst-ungetc-use-libsupport.patch
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
From 87a1968a72e4b4e5436f3e2be1ed8a8d5a5862c7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Wed, 14 Aug 2024 19:20:04 -0400
|
||||||
|
Subject: [PATCH] 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)
|
||||||
|
---
|
||||||
|
stdio-common/tst-ungetc.c | 112 +++++++++++++++++++-------------------
|
||||||
|
1 file changed, 57 insertions(+), 55 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/stdio-common/tst-ungetc.c b/stdio-common/tst-ungetc.c
|
||||||
|
index 1344b2b591..5c808f0734 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>
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
18
glibc.spec
18
glibc.spec
@ -67,7 +67,7 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
Name: glibc
|
Name: glibc
|
||||||
Version: 2.38
|
Version: 2.38
|
||||||
Release: 37
|
Release: 38
|
||||||
Summary: The GNU libc libraries
|
Summary: The GNU libc libraries
|
||||||
License: %{all_license}
|
License: %{all_license}
|
||||||
URL: http://www.gnu.org/software/glibc/
|
URL: http://www.gnu.org/software/glibc/
|
||||||
@ -215,6 +215,13 @@ Patch125: 0012-resolv-Fix-tst-resolv-short-response-for-older-GCC-b.patch
|
|||||||
Patch126: Fix-name-space-violation-in-fortify-wrappers-bug-320.patch
|
Patch126: Fix-name-space-violation-in-fortify-wrappers-bug-320.patch
|
||||||
Patch127: x86-Fix-bug-in-strchrnul-evex512-BZ-32078.patch
|
Patch127: x86-Fix-bug-in-strchrnul-evex512-BZ-32078.patch
|
||||||
Patch128: 19614-locale-Handle-loading-a-missing-locale-twice-Bug-14.patch
|
Patch128: 19614-locale-Handle-loading-a-missing-locale-twice-Bug-14.patch
|
||||||
|
Patch129: support-Add-FAIL-test-failure-helper.patch
|
||||||
|
Patch130: stdio-common-Add-test-for-vfscanf-with-matches-longe.patch
|
||||||
|
Patch131: Make-tst-ungetc-use-libsupport.patch
|
||||||
|
Patch132: ungetc-Fix-uninitialized-read-when-putting-into-unus.patch
|
||||||
|
Patch133: ungetc-Fix-backup-buffer-leak-on-program-exit-BZ-278.patch
|
||||||
|
Patch134: posix-Use-support-check.h-facilities-in-tst-truncate.patch
|
||||||
|
Patch135: nptl-Use-support-check.h-facilities-in-tst-setuid3.patch
|
||||||
|
|
||||||
#openEuler patch list
|
#openEuler patch list
|
||||||
Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch
|
Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch
|
||||||
@ -1447,6 +1454,15 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Sep 9 2024 Qingqing Li <liqingqing3@huawei.com> - 2.38-38
|
||||||
|
- nptl: Use <support/check.h> facilities in tst-setuid3
|
||||||
|
- posix: Use <support/check.h> facilities in tst-truncate and tst-truncate64
|
||||||
|
- ungetc: Fix backup buffer leak on program exit [BZ #27821]
|
||||||
|
- ungetc: Fix uninitialized read when putting into unused streams [BZ #27821]
|
||||||
|
- Make tst-ungetc use libsupport
|
||||||
|
- stdio-common: Add test for vfscanf with matches longer than INT_MAX [BZ #27650]
|
||||||
|
- support: Add FAIL test failure helper
|
||||||
|
|
||||||
* Wed Sep 4 2024 Zhaoshuang <zhaoshuang@uniontech.com> - 2.38-37
|
* Wed Sep 4 2024 Zhaoshuang <zhaoshuang@uniontech.com> - 2.38-37
|
||||||
- Fix issue that loading a missing locale twice [BZ #14247]
|
- Fix issue that loading a missing locale twice [BZ #14247]
|
||||||
|
|
||||||
|
|||||||
134
nptl-Use-support-check.h-facilities-in-tst-setuid3.patch
Normal file
134
nptl-Use-support-check.h-facilities-in-tst-setuid3.patch
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
From f30501ca7557a194a53af22ff5b47b3189c48216 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Maciej W. Rozycki" <macro@redhat.com>
|
||||||
|
Date: Fri, 26 Jul 2024 13:21:34 +0100
|
||||||
|
Subject: [PATCH] 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)
|
||||||
|
---
|
||||||
|
sysdeps/pthread/tst-setuid3.c | 37 +++++++++++++++--------------------
|
||||||
|
1 file changed, 16 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/pthread/tst-setuid3.c b/sysdeps/pthread/tst-setuid3.c
|
||||||
|
index 58b78d3116..d13848a647 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;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
89
posix-Use-support-check.h-facilities-in-tst-truncate.patch
Normal file
89
posix-Use-support-check.h-facilities-in-tst-truncate.patch
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
From 15ca66303f7a7ce463bb41a83d88474996e46efd Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Maciej W. Rozycki" <macro@redhat.com>
|
||||||
|
Date: Fri, 26 Jul 2024 13:21:34 +0100
|
||||||
|
Subject: [PATCH] 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)
|
||||||
|
---
|
||||||
|
posix/tst-truncate-common.c | 25 ++++++++++++-------------
|
||||||
|
1 file changed, 12 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/posix/tst-truncate-common.c b/posix/tst-truncate-common.c
|
||||||
|
index 9a8163fdfe..fd32eb73c5 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;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
176
stdio-common-Add-test-for-vfscanf-with-matches-longe.patch
Normal file
176
stdio-common-Add-test-for-vfscanf-with-matches-longe.patch
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
From 99ffa84bdcdc3d81e82f448279f0c8278dd30964 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Maciej W. Rozycki" <macro@redhat.com>
|
||||||
|
Date: Fri, 26 Jul 2024 13:21:34 +0100
|
||||||
|
Subject: [PATCH] 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)
|
||||||
|
---
|
||||||
|
stdio-common/Makefile | 5 ++
|
||||||
|
stdio-common/tst-scanf-bz27650.c | 108 +++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 113 insertions(+)
|
||||||
|
create mode 100644 stdio-common/tst-scanf-bz27650.c
|
||||||
|
|
||||||
|
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
|
||||||
|
index 3866362bae..2bcbaf754a 100644
|
||||||
|
--- a/stdio-common/Makefile
|
||||||
|
+++ b/stdio-common/Makefile
|
||||||
|
@@ -243,6 +243,7 @@ tests := \
|
||||||
|
tst-scanf-binary-c2x \
|
||||||
|
tst-scanf-binary-gnu11 \
|
||||||
|
tst-scanf-binary-gnu89 \
|
||||||
|
+ tst-scanf-bz27650 \
|
||||||
|
tst-scanf-round \
|
||||||
|
tst-scanf-to_inpunct \
|
||||||
|
tst-setvbuf1 \
|
||||||
|
@@ -312,6 +313,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
|
||||||
|
@@ -398,6 +400,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 0000000000..3a742bc865
|
||||||
|
--- /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>
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
201
support-Add-FAIL-test-failure-helper.patch
Normal file
201
support-Add-FAIL-test-failure-helper.patch
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
From 28f358bc4209ab0425170cdccf65bb1fe861148f Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Maciej W. Rozycki" <macro@redhat.com>
|
||||||
|
Date: Fri, 26 Jul 2024 13:21:34 +0100
|
||||||
|
Subject: [PATCH] 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)
|
||||||
|
---
|
||||||
|
localedata/tst-ctype.c | 40 +++++++++-------------------------------
|
||||||
|
math/test-tgmath2.c | 13 +++----------
|
||||||
|
support/check.h | 5 +++++
|
||||||
|
3 files changed, 17 insertions(+), 41 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/localedata/tst-ctype.c b/localedata/tst-ctype.c
|
||||||
|
index 098bf51335..355b666866 100644
|
||||||
|
--- a/localedata/tst-ctype.c
|
||||||
|
+++ b/localedata/tst-ctype.c
|
||||||
|
@@ -21,6 +21,8 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
|
||||||
|
static const char lower[] = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
static const char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
@@ -53,19 +55,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;
|
||||||
|
@@ -394,11 +388,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;
|
||||||
|
}
|
||||||
|
@@ -408,11 +399,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;
|
||||||
|
}
|
||||||
|
@@ -422,11 +410,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;
|
||||||
|
}
|
||||||
|
@@ -436,14 +421,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 6dd0d64da5..deba439e0c 100644
|
||||||
|
--- a/math/test-tgmath2.c
|
||||||
|
+++ b/math/test-tgmath2.c
|
||||||
|
@@ -24,6 +24,8 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <tgmath.h>
|
||||||
|
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
//#define DEBUG
|
||||||
|
|
||||||
|
typedef complex float cfloat;
|
||||||
|
@@ -87,13 +89,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 \
|
||||||
|
{ \
|
||||||
|
@@ -133,8 +128,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);
|
||||||
|
@@ -152,7 +145,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 e6ae39f1a1..0a9fff484f 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(...) \
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
145
ungetc-Fix-backup-buffer-leak-on-program-exit-BZ-278.patch
Normal file
145
ungetc-Fix-backup-buffer-leak-on-program-exit-BZ-278.patch
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
From b9f72bd5de931eac39219018c2fa319a449bb2cf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Tue, 13 Aug 2024 21:08:49 -0400
|
||||||
|
Subject: [PATCH] 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)
|
||||||
|
---
|
||||||
|
libio/genops.c | 6 ++++++
|
||||||
|
libio/libioP.h | 4 ++--
|
||||||
|
stdio-common/Makefile | 7 +++++++
|
||||||
|
stdio-common/tst-ungetc-leak.c | 32 ++++++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 47 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 stdio-common/tst-ungetc-leak.c
|
||||||
|
|
||||||
|
diff --git a/libio/genops.c b/libio/genops.c
|
||||||
|
index c673c0acec..fb06245467 100644
|
||||||
|
--- a/libio/genops.c
|
||||||
|
+++ b/libio/genops.c
|
||||||
|
@@ -789,6 +789,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 745278e076..e75ee770bc 100644
|
||||||
|
--- a/libio/libioP.h
|
||||||
|
+++ b/libio/libioP.h
|
||||||
|
@@ -577,8 +577,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 2bcbaf754a..381040570b 100644
|
||||||
|
--- a/stdio-common/Makefile
|
||||||
|
+++ b/stdio-common/Makefile
|
||||||
|
@@ -256,6 +256,7 @@ tests := \
|
||||||
|
tst-swscanf \
|
||||||
|
tst-tmpnam \
|
||||||
|
tst-ungetc \
|
||||||
|
+ tst-ungetc-leak \
|
||||||
|
tst-unlockedio \
|
||||||
|
tst-vfprintf-mbs-prec \
|
||||||
|
tst-vfprintf-user-type \
|
||||||
|
@@ -300,6 +301,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
|
||||||
|
|
||||||
|
@@ -314,6 +316,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
|
||||||
|
@@ -403,6 +407,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 0000000000..6c5152b43f
|
||||||
|
--- /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>
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
78
ungetc-Fix-uninitialized-read-when-putting-into-unus.patch
Normal file
78
ungetc-Fix-uninitialized-read-when-putting-into-unus.patch
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
From 804d3c8db79db204154dcf5e11a76f14fdddc570 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Tue, 13 Aug 2024 21:00:06 -0400
|
||||||
|
Subject: [PATCH] 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)
|
||||||
|
---
|
||||||
|
libio/genops.c | 2 +-
|
||||||
|
manual/stdio.texi | 8 +++-----
|
||||||
|
stdio-common/tst-ungetc.c | 2 ++
|
||||||
|
3 files changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libio/genops.c b/libio/genops.c
|
||||||
|
index fbd8dd9e75..c673c0acec 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 9cf622403f..a54cd369db 100644
|
||||||
|
--- a/manual/stdio.texi
|
||||||
|
+++ b/manual/stdio.texi
|
||||||
|
@@ -1474,11 +1474,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 5c808f0734..388b202493 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);
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user