From 14e4554e308467e7426f7bf957e53c1c347e43b0 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Thu, 23 Jan 2025 23:18:58 +0100 Subject: [PATCH] Add tests extracted from upstream printf regression tests (RHEL-46761) Resolves: RHEL-46761 --- glibc-RHEL-46761-1.patch | 76 ++++++++++++++++ glibc-RHEL-46761-2.patch | 183 +++++++++++++++++++++++++++++++++++++++ glibc-RHEL-46761-3.patch | 102 ++++++++++++++++++++++ glibc-RHEL-46761-4.patch | 17 ++++ glibc.spec | 9 +- 5 files changed, 386 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-46761-1.patch create mode 100644 glibc-RHEL-46761-2.patch create mode 100644 glibc-RHEL-46761-3.patch create mode 100644 glibc-RHEL-46761-4.patch diff --git a/glibc-RHEL-46761-1.patch b/glibc-RHEL-46761-1.patch new file mode 100644 index 0000000..b9ad9a0 --- /dev/null +++ b/glibc-RHEL-46761-1.patch @@ -0,0 +1,76 @@ +commit ca6466e8be32369a658035d69542d47603e58a99 +Author: Andreas Schwab +Date: Mon Aug 29 15:05:40 2022 +0200 + + Add test for bug 29530 + + This tests for a bug that was introduced in commit edc1686af0 ("vfprintf: + Reuse work_buffer in group_number") and fixed as a side effect of commit + 6caddd34bd ("Remove most vfprintf width/precision-dependent allocations + (bug 14231, bug 26211)."). + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 826823a68dd36a8a..e3939b112ca2037f 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -221,6 +221,7 @@ tests := \ + tst-getline-enomem \ + tst-gets \ + tst-grouping \ ++ tst-grouping2 \ + tst-long-dbl-fphex \ + tst-obprintf \ + tst-perror \ +@@ -369,6 +370,7 @@ $(objpfx)bug14.out: $(gen-locales) + $(objpfx)scanf13.out: $(gen-locales) + $(objpfx)test-vfprintf.out: $(gen-locales) + $(objpfx)tst-grouping.out: $(gen-locales) ++$(objpfx)tst-grouping2.out: $(gen-locales) + $(objpfx)tst-sprintf.out: $(gen-locales) + $(objpfx)tst-sscanf.out: $(gen-locales) + $(objpfx)tst-swprintf.out: $(gen-locales) +diff --git a/stdio-common/tst-grouping2.c b/stdio-common/tst-grouping2.c +new file mode 100644 +index 0000000000000000..3024c942a60e51bf +--- /dev/null ++++ b/stdio-common/tst-grouping2.c +@@ -0,0 +1,39 @@ ++/* Test printf with grouping and large width (bug 29530) ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ const int field_width = 1000; ++ char buf[field_width + 1]; ++ ++ xsetlocale (LC_NUMERIC, "de_DE.UTF-8"); ++ ++ /* This used to crash in group_number. */ ++ TEST_COMPARE (sprintf (buf, "%'*d", field_width, 1000), field_width); ++ TEST_COMPARE_STRING (buf + field_width - 6, " 1.000"); ++ ++ return 0; ++} ++ ++#include diff --git a/glibc-RHEL-46761-2.patch b/glibc-RHEL-46761-2.patch new file mode 100644 index 0000000..4fc62b2 --- /dev/null +++ b/glibc-RHEL-46761-2.patch @@ -0,0 +1,183 @@ +Backport of the test case from this commit: + +commit 0d50f477f47ba637b54fb03ac48d769ec4543e8d +Author: Florian Weimer +Date: Wed Jan 25 08:01:00 2023 +0100 + + stdio-common: Handle -1 buffer size in __sprintf_chk & co (bug 30039) + + This shows up as an assertion failure when sprintf is called with + a specifier like "%.8g" and libquadmath is linked in: + + Fatal glibc error: printf_buffer_as_file.c:31 + (__printf_buffer_as_file_commit): assertion failed: + file->stream._IO_write_ptr <= file->next->write_end + + Fix this by detecting pointer wraparound in __vsprintf_internal + and saturate the addition to the end of the address space instead. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + +Conflicts: + debug/Makefile + (missing time64 tests downstream) + include/printf_buffer.h + libio/iovsprintf.c + (not included in test-only backport) + +diff --git a/debug/Makefile b/debug/Makefile +index ddae3817aef9afad..563e6249121e8bc9 100644 +--- a/debug/Makefile ++++ b/debug/Makefile +@@ -187,6 +187,10 @@ LDFLAGS-tst-backtrace6 = -rdynamic + + CFLAGS-tst-ssp-1.c += -fstack-protector-all + ++# Disable compiler optimizations around vsprintf (the function under test). ++CFLAGS-tst-sprintf-fortify-unchecked.c = \ ++ -fno-builtin-vsprintf -fno-builtin-__vsprintf_chk ++ + tests = backtrace-tst \ + tst-longjmp_chk \ + test-strcpy_chk \ +@@ -199,6 +203,7 @@ tests = backtrace-tst \ + tst-backtrace5 \ + tst-backtrace6 \ + tst-realpath-chk \ ++ tst-sprintf-fortify-unchecked \ + $(tests-all-chk) \ + + ifeq ($(have-ssp),yes) +diff --git a/debug/tst-sprintf-fortify-unchecked.c b/debug/tst-sprintf-fortify-unchecked.c +new file mode 100644 +index 0000000000000000..7c7bd1b5e4fe12e8 +--- /dev/null ++++ b/debug/tst-sprintf-fortify-unchecked.c +@@ -0,0 +1,126 @@ ++/* Tests for fortified sprintf with unknown buffer bounds (bug 30039). ++ Copyright (C) 2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* This test is not built with _FORTIFY_SOURCE. Instead it calls the ++ appropriate implementation directly. The fortify mode is specified ++ in this variable. */ ++static int fortify_mode; ++ ++/* This does not handle long-double redirects etc., but we test only ++ format strings that stay within the confines of the base ++ implementation. */ ++int __vsprintf_chk (char *s, int flag, size_t slen, const char *format, ++ va_list ap); ++ ++/* Invoke vsprintf or __vsprintf_chk according to fortify_mode. */ ++static int ++my_vsprintf (char *buf, const char *format, va_list ap) ++{ ++ int result; ++ if (fortify_mode == 0) ++ result = vsprintf (buf, format, ap); ++ else ++ /* Call the fortified version with an unspecified length. */ ++ result = __vsprintf_chk (buf, fortify_mode - 1, -1, format, ap); ++ return result; ++} ++ ++/* Run one test, with the specified expected output. */ ++static void __attribute ((format (printf, 2, 3))) ++do_check (const char *expected, const char *format, ...) ++{ ++ va_list ap; ++ va_start (ap, format); ++ ++ char buf_expected[24]; ++ memset (buf_expected, '@', sizeof (buf_expected)); ++ TEST_VERIFY (strlen (expected) < sizeof (buf_expected)); ++ strcpy (buf_expected, expected); ++ ++ char buf[sizeof (buf_expected)]; ++ memset (buf, '@', sizeof (buf)); ++ ++ int ret = my_vsprintf (buf, format, ap); ++ TEST_COMPARE_BLOB (buf_expected, sizeof (buf_expected), buf, sizeof (buf)); ++ TEST_COMPARE (ret, strlen (expected)); ++ ++ va_end (ap); ++} ++ ++/* Run the tests in all fortify modes. */ ++static void ++do_tests (void) ++{ ++ for (fortify_mode = 0; fortify_mode <= 3; ++fortify_mode) ++ { ++ do_check ("0", "%d", 0); ++ do_check ("-2147483648", "%d", -2147483647 - 1); ++ do_check ("-9223372036854775808", "%lld", -9223372036854775807LL - 1); ++ do_check ("", "%s", ""); ++ do_check (" ", "%22s", ""); ++ do_check ("XXXXXXXXXXXXXXXXXXXXXX", "%s", "XXXXXXXXXXXXXXXXXXXXXX"); ++ do_check ("1.125000", "%f", 1.125); ++ do_check ("1.125", "%g", 1.125); ++ do_check ("1.125", "%.8g", 1.125); ++ } ++} ++ ++/* printf callback that falls back to the glibc-supplied ++ implementation. */ ++static int ++dummy_printf_function (FILE *__stream, ++ const struct printf_info *__info, ++ const void *const *__args) ++{ ++ return -2; /* Request fallback. */ ++} ++ ++/* Likewise for the type information. */ ++static int ++dummy_arginfo_function (const struct printf_info *info, ++ size_t n, int *argtypes, int *size) ++{ ++ return -1; /* Request fallback. */ ++} ++ ++static int ++do_test (void) ++{ ++ do_tests (); ++ ++ /* Activate __printf_function_invoke mode. */ ++ register_printf_specifier ('d', dummy_printf_function, ++ dummy_arginfo_function); ++ register_printf_specifier ('g', dummy_printf_function, ++ dummy_arginfo_function); ++ register_printf_specifier ('s', dummy_printf_function, ++ dummy_arginfo_function); ++ ++ /* Rerun the tests with callback functions. */ ++ do_tests (); ++ ++ return 0; ++} ++ ++#include diff --git a/glibc-RHEL-46761-3.patch b/glibc-RHEL-46761-3.patch new file mode 100644 index 0000000..2766eb6 --- /dev/null +++ b/glibc-RHEL-46761-3.patch @@ -0,0 +1,102 @@ +Backport of the test case from the upstream commit. Note +that the test fails in the version included here. + +commit c980549cc6a1c03c23cc2fe3e7b0fe626a0364b0 +Author: Carlos O'Donell +Date: Thu Jan 19 12:50:20 2023 +0100 + + Account for grouping in printf width (bug 30068) + + This is a partial fix for mishandling of grouping when formatting + integers. It properly computes the width in the presence of grouping + characters when the width is larger than the number of significant + digits. The precision related issue is documented in bug 23432. + + Co-authored-by: Andreas Schwab + +Conflicts: + stdio-common/Makefile + (missing tests downstream) + stdio-common/vfprintf-process-arg.c + (not included in backport) + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index e3939b112ca2037f..74e0edff73a9e468 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -222,6 +222,7 @@ tests := \ + tst-gets \ + tst-grouping \ + tst-grouping2 \ ++ tst-grouping3 \ + tst-long-dbl-fphex \ + tst-obprintf \ + tst-perror \ +@@ -375,6 +376,7 @@ $(objpfx)tst-sprintf.out: $(gen-locales) + $(objpfx)tst-sscanf.out: $(gen-locales) + $(objpfx)tst-swprintf.out: $(gen-locales) + $(objpfx)tst-vfprintf-mbs-prec.out: $(gen-locales) ++$(objpfx)tst-grouping3.out: $(gen-locales) + endif + + tst-printf-bz18872-ENV = MALLOC_TRACE=$(objpfx)tst-printf-bz18872.mtrace \ +diff --git a/stdio-common/tst-grouping3.c b/stdio-common/tst-grouping3.c +new file mode 100644 +index 0000000000000000..e9e39218e25a2720 +--- /dev/null ++++ b/stdio-common/tst-grouping3.c +@@ -0,0 +1,54 @@ ++/* Test printf with grouping and padding (bug 30068) ++ Copyright (C) 2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ char buf[80]; ++ ++ xsetlocale (LC_NUMERIC, "de_DE.UTF-8"); ++ ++ /* The format string has the following conversion specifier: ++ ' - Use thousands grouping. ++ + - The result of a signed conversion shall begin with a sign. ++ - - Left justified. ++ 13 - Minimum 13 bytes of width. ++ 9 - Minimum 9 digits of precision. ++ ++ In bug 30068 the grouping characters were not accounted for in ++ the width, and were added after the fact resulting in a 15-byte ++ output instead of a 13-byte output. The two additional bytes ++ come from the locale-specific thousands separator. This increase ++ in size could result in a buffer overflow if a reasonable caller ++ calculated the size of the expected buffer using nl_langinfo to ++ determine the sie of THOUSEP in bytes. ++ ++ This bug is distinct from bug 23432 which has to do with the ++ minimum precision calculation (digit based). */ ++ sprintf (buf, "%+-'13.9d", 1234567); ++ TEST_COMPARE_STRING (buf, "+001.234.567 "); ++ ++ return 0; ++} ++ ++#include diff --git a/glibc-RHEL-46761-4.patch b/glibc-RHEL-46761-4.patch new file mode 100644 index 0000000..7c0e958 --- /dev/null +++ b/glibc-RHEL-46761-4.patch @@ -0,0 +1,17 @@ +Adjust the test expectation for stdio-common/tst-grouping3 to match +the state of the RHEL 9 printf implementation, which does not add +zero padding when grouping integers. + +diff --git a/stdio-common/tst-grouping3.c b/stdio-common/tst-grouping3.c +index e9e39218e25a2720..5a247cfe3fb8564f 100644 +--- a/stdio-common/tst-grouping3.c ++++ b/stdio-common/tst-grouping3.c +@@ -46,7 +46,7 @@ do_test (void) + This bug is distinct from bug 23432 which has to do with the + minimum precision calculation (digit based). */ + sprintf (buf, "%+-'13.9d", 1234567); +- TEST_COMPARE_STRING (buf, "+001.234.567 "); ++ TEST_COMPARE_STRING (buf, "+1.234.567 "); + + return 0; + } diff --git a/glibc.spec b/glibc.spec index cd947b9..82c8929 100644 --- a/glibc.spec +++ b/glibc.spec @@ -157,7 +157,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 157%{?dist} +Release: 158%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -1086,6 +1086,10 @@ Patch778: glibc-RHEL-65359-2.patch Patch779: glibc-RHEL-65359-3.patch Patch780: glibc-RHEL-65359-4.patch Patch781: glibc-RHEL-75810.patch +Patch782: glibc-RHEL-46761-1.patch +Patch783: glibc-RHEL-46761-2.patch +Patch784: glibc-RHEL-46761-3.patch +Patch785: glibc-RHEL-46761-4.patch ############################################################################## # Continued list of core "glibc" package information: @@ -3079,6 +3083,9 @@ update_gconv_modules_cache () %endif %changelog +* Thu Jan 23 2025 Florian Weimer - 2.34-158 +- Add tests extracted from upstream printf regression tests (RHEL-46761) + * Thu Jan 23 2025 Florian Weimer - 2.34-157 - Restore compatibility with environ/malloc usage pattern (RHEL-75810)