diff --git a/SOURCES/coreutils-8.32-df-fix-mishandled-automounts.patch b/SOURCES/coreutils-8.32-df-fix-mishandled-automounts.patch new file mode 100644 index 0000000..099b7fd --- /dev/null +++ b/SOURCES/coreutils-8.32-df-fix-mishandled-automounts.patch @@ -0,0 +1,75 @@ +From 76c1da7ecf69bfe8a928f03304919f75e819e694 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Wed, 11 Aug 2021 11:16:05 -0700 +Subject: df: fix bug with automounted + +If the command-line argument is automounted, df would use +stat info that became wrong after the following open. +* src/df.c (automount_stat_err): New function. +This fixes the hang on fifos in a better way, by using O_NONBLOCK. +(main): Use it. + +(cherry picked from commit a3c04f8da14f0fe2a0561bf5562032b8ce5dafa9) +--- + src/df.c | 34 +++++++++++++++++++++++++--------- + 1 file changed, 25 insertions(+), 9 deletions(-) + +diff --git a/src/df.c b/src/df.c +index 99989399f..841b7715b 100644 +--- a/src/df.c ++++ b/src/df.c +@@ -276,6 +276,28 @@ static struct option const long_options[] = + {NULL, 0, NULL, 0} + }; + ++/* Stat FILE and put the results into *ST. Return 0 if successful, an ++ error number otherwise. Try to open FILE before statting, to ++ trigger automounts. */ ++ ++static int ++automount_stat_err (char const *file, struct stat *st) ++{ ++ int fd = open (file, O_RDONLY | O_NOCTTY | O_NONBLOCK); ++ if (fd < 0) ++ { ++ if (errno == ENOENT || errno == ENOTDIR) ++ return errno; ++ return stat (file, st) == 0 ? 0 : errno; ++ } ++ else ++ { ++ int err = fstat (fd, st) == 0 ? 0 : errno; ++ close (fd); ++ return err; ++ } ++} ++ + /* Replace problematic chars with '?'. + Since only control characters are currently considered, + this should work in all encodings. */ +@@ -1772,19 +1794,13 @@ main (int argc, char **argv) + stats = xnmalloc (argc - optind, sizeof *stats); + for (int i = optind; i < argc; ++i) + { +- if (stat (argv[i], &stats[i - optind])) ++ int err = automount_stat_err (argv[i], &stats[i - optind]); ++ if (err != 0) + { +- error (0, errno, "%s", quotef (argv[i])); ++ error (0, err, "%s", quotef (argv[i])); + exit_status = EXIT_FAILURE; + argv[i] = NULL; + } +- else if (! S_ISFIFO (stats[i - optind].st_mode)) +- { +- /* open() is needed to automount in some cases. */ +- int fd = open (argv[i], O_RDONLY | O_NOCTTY); +- if (0 <= fd) +- close (fd); +- } + } + } + +-- +2.54.0 + diff --git a/SOURCES/coreutils-CVE-2025-5278.patch b/SOURCES/coreutils-CVE-2025-5278.patch new file mode 100644 index 0000000..f001bbb --- /dev/null +++ b/SOURCES/coreutils-CVE-2025-5278.patch @@ -0,0 +1,107 @@ +From ec1b9be71e9c033e48c40cac58d784a94d6d3179 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Tue, 20 May 2025 16:03:44 +0100 +Subject: [PATCH] sort: fix buffer under-read (CWE-127) + +* src/sort.c (begfield): Check pointer adjustment +to avoid Out-of-range pointer offset (CWE-823). +(limfield): Likewise. +* tests/sort/sort-field-limit.sh: Add a new test, +which triggers with ASAN or Valgrind. +* tests/local.mk: Reference the new test. +Fixes https://bugs.gnu.org/78507 + +(cherry picked from commit 8c9602e3a145e9596dc1a63c6ed67865814b6633) +--- + src/sort.c | 12 ++++++++++-- + tests/local.mk | 1 + + tests/sort/sort-field-limit.sh | 35 ++++++++++++++++++++++++++++++++++ + 3 files changed, 46 insertions(+), 2 deletions(-) + create mode 100755 tests/sort/sort-field-limit.sh + +diff --git a/src/sort.c b/src/sort.c +index 329ed45dc..a78dbf713 100644 +--- a/src/sort.c ++++ b/src/sort.c +@@ -1643,7 +1643,11 @@ begfield (struct line const *line, struct keyfield const *key) + ++ptr; + + /* Advance PTR by SCHAR (if possible), but no further than LIM. */ +- ptr = MIN (lim, ptr + schar); ++ size_t remaining_bytes = lim - ptr; ++ if (schar < remaining_bytes) ++ ptr += schar; ++ else ++ ptr = lim; + + return ptr; + } +@@ -1744,7 +1748,11 @@ limfield (struct line const *line, struct keyfield const *key) + ++ptr; + + /* Advance PTR by ECHAR (if possible), but no further than LIM. */ +- ptr = MIN (lim, ptr + echar); ++ size_t remaining_bytes = lim - ptr; ++ if (echar < remaining_bytes) ++ ptr += echar; ++ else ++ ptr = lim; + } + + return ptr; +diff --git a/tests/local.mk b/tests/local.mk +index a41790799..69cf80f23 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -369,6 +369,7 @@ all_tests = \ + tests/misc/sort-debug-keys.sh \ + tests/misc/sort-debug-warn.sh \ + tests/misc/sort-discrim.sh \ ++ tests/sort/sort-field-limit.sh \ + tests/misc/sort-files0-from.pl \ + tests/misc/sort-float.sh \ + tests/misc/sort-h-thousands-sep.sh \ +diff --git a/tests/sort/sort-field-limit.sh b/tests/sort/sort-field-limit.sh +new file mode 100755 +index 000000000..52d8e1d17 +--- /dev/null ++++ b/tests/sort/sort-field-limit.sh +@@ -0,0 +1,35 @@ ++#!/bin/sh ++# From 7.2-9.7, this would trigger an out of bounds mem read ++ ++# Copyright (C) 2025 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program 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 General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ sort ++getlimits_ ++ ++# This issue triggers with valgrind or ASAN ++valgrind --error-exitcode=1 sort --version 2>/dev/null && ++ VALGRIND='valgrind --error-exitcode=1' ++ ++{ printf '%s\n' aa bb; } > in || framework_failure_ ++ ++_POSIX2_VERSION=200809 $VALGRIND sort +0.${SIZE_MAX}R in > out || fail=1 ++compare in out || fail=1 ++ ++_POSIX2_VERSION=200809 $VALGRIND sort +1 -1.${SIZE_MAX}R in > out || fail=1 ++compare in out || fail=1 ++ ++Exit $fail +-- +2.54.0 + diff --git a/SOURCES/coreutils-df-direct.patch b/SOURCES/coreutils-df-direct.patch index 88015a1..4d7915f 100644 --- a/SOURCES/coreutils-df-direct.patch +++ b/SOURCES/coreutils-df-direct.patch @@ -7,11 +7,12 @@ Subject: [PATCH] coreutils-df-direct.patch doc/coreutils.texi | 7 ++++++ src/df.c | 34 ++++++++++++++++++++++++++-- tests/df/direct.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 94 insertions(+), 2 deletions(-) + tests/local.mk | 1 + + 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 5b9a597..6810c15 100644 +index 904ba0a..93c4eca 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -11898,6 +11898,13 @@ some systems (notably SunOS), doing this yields more up to date results, @@ -29,7 +30,7 @@ index 5b9a597..6810c15 100644 @opindex --total @cindex grand total of disk size, usage and available space diff --git a/src/df.c b/src/df.c -index 48025b9..c8efa5b 100644 +index 9998939..bdcfba0 100644 --- a/src/df.c +++ b/src/df.c @@ -125,6 +125,9 @@ static bool print_type; @@ -123,7 +124,7 @@ index 48025b9..c8efa5b 100644 if (posix_format) diff --git a/tests/df/direct.sh b/tests/df/direct.sh new file mode 100755 -index 0000000..8e4cfb8 +index 0000000..8373705 --- /dev/null +++ b/tests/df/direct.sh @@ -0,0 +1,55 @@ @@ -145,7 +146,7 @@ index 0000000..8e4cfb8 +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + -+. "${srcdir=.}/init.sh"; path_prepend_ ../src ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ df + +df || skip_ "df fails" @@ -182,6 +183,18 @@ index 0000000..8e4cfb8 +compare file_out file_exp || fail=1 + +Exit $fail +diff --git a/tests/local.mk b/tests/local.mk +index a417907..d07601e 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -524,6 +524,7 @@ all_tests = \ + tests/df/no-mtab-status.sh \ + tests/df/skip-duplicates.sh \ + tests/df/skip-rootfs.sh \ ++ tests/df/direct.sh \ + tests/dd/ascii.sh \ + tests/dd/direct.sh \ + tests/dd/misc.sh \ -- -2.31.1 +2.53.0 diff --git a/SOURCES/coreutils-i18n-expand-unexpand.patch b/SOURCES/coreutils-i18n-expand-unexpand.patch index 6cccdf6..5a9b983 100644 --- a/SOURCES/coreutils-i18n-expand-unexpand.patch +++ b/SOURCES/coreutils-i18n-expand-unexpand.patch @@ -20,15 +20,15 @@ Co-authored-by: Pádraig Brady bootstrap.conf | 1 + configure.ac | 2 + lib/mbfile.c | 3 + - lib/mbfile.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++ + lib/mbfile.h | 255 +++++++++++++++++++++++++++++++++++++++++++ m4/mbfile.m4 | 14 +++ - src/expand.c | 43 +++++---- + src/expand.c | 43 +++++--- src/local.mk | 4 +- - src/unexpand.c | 54 +++++++---- - tests/expand/mb.sh | 98 ++++++++++++++++++++ + src/unexpand.c | 59 ++++++---- + tests/expand/mb.sh | 98 +++++++++++++++++ tests/local.mk | 2 + - tests/unexpand/mb.sh | 97 ++++++++++++++++++++ - 10 files changed, 535 insertions(+), 34 deletions(-) + tests/unexpand/mb.sh | 114 +++++++++++++++++++ + 11 files changed, 557 insertions(+), 38 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 @@ -36,10 +36,10 @@ Co-authored-by: Pádraig Brady create mode 100755 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index 8a0ff31..a1c78b2 100644 +index 57e8eaf1c..7d53e284b 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -152,6 +152,7 @@ gnulib_modules=" +@@ -155,6 +155,7 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -48,10 +48,10 @@ index 8a0ff31..a1c78b2 100644 mbrtowc mbsalign diff --git a/configure.ac b/configure.ac -index 1e74b36..24c9725 100644 +index c2ad08c39..f5da8163e 100644 --- a/configure.ac +++ b/configure.ac -@@ -427,6 +427,8 @@ fi +@@ -446,6 +446,8 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -62,7 +62,7 @@ index 1e74b36..24c9725 100644 if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ diff --git a/lib/mbfile.c b/lib/mbfile.c new file mode 100644 -index 0000000..b0a468e +index 000000000..b0a468efa --- /dev/null +++ b/lib/mbfile.c @@ -0,0 +1,3 @@ @@ -71,7 +71,7 @@ index 0000000..b0a468e +#include "mbfile.h" diff --git a/lib/mbfile.h b/lib/mbfile.h new file mode 100644 -index 0000000..11f1b12 +index 000000000..11f1b1242 --- /dev/null +++ b/lib/mbfile.h @@ -0,0 +1,255 @@ @@ -332,7 +332,7 @@ index 0000000..11f1b12 +#endif /* _MBFILE_H */ diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 new file mode 100644 -index 0000000..8589902 +index 000000000..858990213 --- /dev/null +++ b/m4/mbfile.m4 @@ -0,0 +1,14 @@ @@ -351,7 +351,7 @@ index 0000000..8589902 + : +]) diff --git a/src/expand.c b/src/expand.c -index 9fa2e10..380e020 100644 +index 3412d7b09..ec91d01e9 100644 --- a/src/expand.c +++ b/src/expand.c @@ -37,6 +37,9 @@ @@ -364,7 +364,7 @@ index 9fa2e10..380e020 100644 #include "system.h" #include "die.h" #include "xstrndup.h" -@@ -100,19 +103,19 @@ expand (void) +@@ -98,19 +101,19 @@ expand (void) { /* Input stream. */ FILE *fp = next_file (NULL); @@ -388,7 +388,7 @@ index 9fa2e10..380e020 100644 /* The following variables have valid values only when CONVERT is true: */ -@@ -122,17 +125,23 @@ expand (void) +@@ -120,17 +123,23 @@ expand (void) /* Index in TAB_LIST of next tab stop to examine. */ size_t tab_index = 0; @@ -416,7 +416,7 @@ index 9fa2e10..380e020 100644 { /* Column the next input tab stop is on. */ uintmax_t next_tab_column; -@@ -151,32 +160,34 @@ expand (void) +@@ -149,32 +158,34 @@ expand (void) if (putchar (' ') < 0) die (EXIT_FAILURE, errno, _("write error")); @@ -475,7 +475,7 @@ index 72db9c704..ef3bfa469 100644 # Ensure we don't link against libcoreutils.a as that lib is # not compiled with -fPIC which causes issues on 64 bit at least diff --git a/src/unexpand.c b/src/unexpand.c -index 7801274..569a7ee 100644 +index 09dafdbe1..33f5425f0 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -38,6 +38,9 @@ @@ -507,7 +507,7 @@ index 7801274..569a7ee 100644 tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so allocate MAX_COLUMN_WIDTH bytes to store the blanks. */ - pending_blank = xmalloc (max_column_width); -+ pending_blank = xmalloc (max_column_width * sizeof (mbf_char_t)); ++ pending_blank = xnmalloc (max_column_width, sizeof (mbf_char_t)); + + mbf_init (mbf, fp); @@ -542,7 +542,7 @@ index 7801274..569a7ee 100644 if (blank) { -@@ -180,16 +193,16 @@ unexpand (void) +@@ -180,30 +193,31 @@ unexpand (void) if (next_tab_column < column) die (EXIT_FAILURE, 0, _("input line is too long")); @@ -560,9 +560,10 @@ index 7801274..569a7ee 100644 - column++; + column += mb_width (c); - if (! (prev_blank && column == next_tab_column)) +- if (! (prev_blank && column == next_tab_column)) ++ if (! (prev_blank && column >= next_tab_column)) { -@@ -197,13 +210,14 @@ unexpand (void) + /* It is not yet known whether the pending blanks will be replaced by tabs. */ if (column == next_tab_column) one_blank_before_tab_stop = true; @@ -636,7 +637,7 @@ index 7801274..569a7ee 100644 diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh new file mode 100755 -index 0000000..7971e18 +index 000000000..dab27b479 --- /dev/null +++ b/tests/expand/mb.sh @@ -0,0 +1,98 @@ @@ -737,12 +738,12 @@ index 0000000..7971e18 +expand < in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 + -+exit $fail ++Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 192f776..8053397 100644 +index 9e366ebed..5bf132ae8 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -544,6 +544,7 @@ all_tests = \ +@@ -573,6 +573,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -750,7 +751,7 @@ index 192f776..8053397 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -684,6 +685,7 @@ all_tests = \ +@@ -720,6 +721,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -760,10 +761,10 @@ index 192f776..8053397 100644 # See tests/factor/create-test.sh. diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh new file mode 100755 -index 0000000..60d4c1a +index 000000000..5b4252d8f --- /dev/null +++ b/tests/unexpand/mb.sh -@@ -0,0 +1,97 @@ +@@ -0,0 +1,114 @@ +#!/bin/sh + +# Copyright (C) 2012-2015 Free Software Foundation, Inc. @@ -783,6 +784,7 @@ index 0000000..60d4c1a + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ unexpand ++getlimits_ + +export LC_ALL=en_US.UTF-8 + @@ -824,7 +826,7 @@ index 0000000..60d4c1a +e\t|ascii(1) +\u00E9\t|composed(1) +e\u0301\t|decomposed(1) -+\u3000\t|ideo-space(2) ++\t|ideo-space(2) +\uFF0D\t|full-hypen(2) +' > exp || framework_failure_ + @@ -846,7 +848,7 @@ index 0000000..60d4c1a +ä\xFF | + ä\xFF| +\xFF ä| -+äbcdef\xFF | ++äbcde\xFF | +' > in || framework_failure_ + +env printf '12345678 @@ -856,11 +858,27 @@ index 0000000..60d4c1a +ä\xFF\t| +\tä\xFF| +\xFF\tä| -+äbcdef\xFF\t| ++äbcde\xFF\t| +' > exp || framework_failure_ + +unexpand -a < in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 ++ ++for mb_mul in 4 6; do ++ printf ' \n' | unexpand -t $(expr $SIZE_MAX / $mb_mul + 1) 2>err; ret=$? ++ test "$ret" = 1 || test "$ret" = 0 || { cat err; fail=1; } ++done ++ ++# A blank whose display width exceeds the tab distance must not overrun ++# the pending-blank buffer. With -t1 every column is a tab stop, so a ++# width-2 ideographic space steps over the stop without landing on it; ++# the run of blanks then grew pending_blank without bound. ++ideo_space=$(env printf '\u3000') ++{ yes "$ideo_space" | head -n 40000 | tr -d '\n'; echo; } | ++ unexpand -t1 >out 2>err; ret=$? ++test "$ret" = 0 || { cat err; fail=1; } ++ ++Exit $fail -- -2.7.4 +2.54.0 diff --git a/SOURCES/coreutils-i18n-fix2-expand-unexpand.patch b/SOURCES/coreutils-i18n-fix2-expand-unexpand.patch index b34d7b7..973f485 100644 --- a/SOURCES/coreutils-i18n-fix2-expand-unexpand.patch +++ b/SOURCES/coreutils-i18n-fix2-expand-unexpand.patch @@ -1,8 +1,8 @@ diff --git a/src/expand.c b/src/expand.c -index 380e020..310b349 100644 +index ec91d01..8144e43 100644 --- a/src/expand.c +++ b/src/expand.c -@@ -129,15 +129,19 @@ expand (void) +@@ -127,15 +127,19 @@ expand (void) do { @@ -27,7 +27,7 @@ index 380e020..310b349 100644 if (convert) { diff --git a/src/unexpand.c b/src/unexpand.c -index 3bbbd66..863a90a 100644 +index e7f4e8a..7a010e2 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -164,15 +164,19 @@ unexpand (void) @@ -55,7 +55,7 @@ index 3bbbd66..863a90a 100644 if (convert) { diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh -index 7971e18..031be7a 100755 +index dab27b4..3a5eb95 100755 --- a/tests/expand/mb.sh +++ b/tests/expand/mb.sh @@ -44,6 +44,20 @@ EOF @@ -80,7 +80,7 @@ index 7971e18..031be7a 100755 env printf '12345678 e\t|ascii(1) diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh -index 60d4c1a..8d75652 100755 +index a7b6ad0..92962f6 100755 --- a/tests/unexpand/mb.sh +++ b/tests/unexpand/mb.sh @@ -44,6 +44,22 @@ EOF diff --git a/SOURCES/coreutils-i18n-un-expand-BOM.patch b/SOURCES/coreutils-i18n-un-expand-BOM.patch index 6210ce7..2b22031 100644 --- a/SOURCES/coreutils-i18n-un-expand-BOM.patch +++ b/SOURCES/coreutils-i18n-un-expand-BOM.patch @@ -4,16 +4,16 @@ Date: Thu, 7 Jul 2016 12:53:26 +0200 Subject: [PATCH] coreutils-i18n-un-expand-BOM.patch --- - src/expand-common.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++ - src/expand-common.h | 12 ++++++ - src/expand.c | 45 +++++++++++++++++++- - src/unexpand.c | 43 ++++++++++++++++++- - tests/expand/mb.sh | 71 ++++++++++++++++++++++++++++++++ - tests/unexpand/mb.sh | 59 ++++++++++++++++++++++++++ - 6 files changed, 342 insertions(+), 2 deletions(-) + src/expand-common.c | 114 +++++++++++++++++++++++++++++++++++++++++++ + src/expand-common.h | 12 +++++ + src/expand.c | 45 ++++++++++++++++- + src/unexpand.c | 43 +++++++++++++++- + tests/expand/mb.sh | 71 +++++++++++++++++++++++++++ + tests/unexpand/mb.sh | 58 ++++++++++++++++++++++ + 6 files changed, 341 insertions(+), 2 deletions(-) diff --git a/src/expand-common.c b/src/expand-common.c -index 4657e46..97cbb09 100644 +index e4209a015..76be4d8d5 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -145,7 +145,7 @@ index 4657e46..97cbb09 100644 to the list of tab stops. */ extern void diff --git a/src/expand-common.h b/src/expand-common.h -index 8cb2079..763bfda 100644 +index f304fbb2b..eaa2f1505 100644 --- a/src/expand-common.h +++ b/src/expand-common.h @@ -34,6 +34,18 @@ extern size_t max_column_width; @@ -168,7 +168,7 @@ index 8cb2079..763bfda 100644 extern void add_tab_stop (uintmax_t tabval); diff --git a/src/expand.c b/src/expand.c -index 310b349..4136824 100644 +index 8144e4344..bf61aff7c 100644 --- a/src/expand.c +++ b/src/expand.c @@ -103,11 +103,33 @@ expand (void) @@ -235,7 +235,7 @@ index 310b349..4136824 100644 } else diff --git a/src/unexpand.c b/src/unexpand.c -index 863a90a..5681b58 100644 +index 95c80712f..345aa5820 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -116,16 +116,36 @@ unexpand (void) @@ -266,7 +266,7 @@ index 863a90a..5681b58 100644 /* The worst case is a non-blank character, then one blank, then a tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so allocate MAX_COLUMN_WIDTH bytes to store the blanks. */ - pending_blank = xmalloc (max_column_width * sizeof (mbf_char_t)); + pending_blank = xnmalloc (max_column_width, sizeof (mbf_char_t)); - mbf_init (mbf, fp); + if (found_bom == true) @@ -305,7 +305,7 @@ index 863a90a..5681b58 100644 } else diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh -index 031be7a..1621c84 100755 +index 3a5eb95c2..6d6497a3d 100755 --- a/tests/expand/mb.sh +++ b/tests/expand/mb.sh @@ -109,4 +109,75 @@ env printf '12345678 @@ -383,16 +383,15 @@ index 031be7a..1621c84 100755 +LC_ALL=C expand in1 in1 > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 + - exit $fail + Exit $fail diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh -index 8d75652..9d4ee3e 100755 +index b1f0b2ea4..4d31ffd33 100755 --- a/tests/unexpand/mb.sh +++ b/tests/unexpand/mb.sh -@@ -111,3 +111,62 @@ env printf '12345678 +@@ -127,4 +127,62 @@ ideo_space=$(env printf '\u3000') + unexpand -t1 >out 2>err; ret=$? + test "$ret" = 0 || { cat err; fail=1; } - unexpand -a < in > out || fail=1 - compare exp out > /dev/null 2>&1 || fail=1 -+ +#BOM header test 1 +printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ +1234567812345678123456781 @@ -403,7 +402,6 @@ index 8d75652..9d4ee3e 100755 +. . . . + äöü . öüä. ä xx +EOF -+env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_ + +printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_ +1234567812345678123456781 @@ -415,13 +413,13 @@ index 8d75652..9d4ee3e 100755 + äöü . öüä. ä xx +EOF + -+unexpand < in > out || fail=1 ++unexpand -a < in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 + -+LANG=C unexpand < in > out || fail=1 ++LANG=C unexpand -a < in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 + -+LC_ALL=C unexpand < in > out || fail=1 ++LC_ALL=C unexpand -a < in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 + + @@ -443,14 +441,16 @@ index 8d75652..9d4ee3e 100755 +EOF + + -+unexpand in in > out || fail=1 ++unexpand -a in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 + -+LANG=C unexpand in in > out || fail=1 ++LANG=C unexpand -a in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 + -+LC_ALL=C unexpand in in > out || fail=1 ++LC_ALL=C unexpand -a in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 ++ + Exit $fail -- -2.9.3 +2.54.0 diff --git a/SOURCES/coreutils-i18n.patch b/SOURCES/coreutils-i18n.patch index c323cff..771ac9e 100644 --- a/SOURCES/coreutils-i18n.patch +++ b/SOURCES/coreutils-i18n.patch @@ -6,7 +6,7 @@ Subject: [PATCH] coreutils-i18n.patch TODO: merge upstream --- lib/linebuffer.h | 8 + - src/fold.c | 308 +++++++++++++-- + src/fold.c | 309 +++++++++++++-- src/join.c | 359 ++++++++++++++--- src/pr.c | 443 +++++++++++++++++++-- src/sort.c | 764 ++++++++++++++++++++++++++++++++++-- @@ -22,12 +22,12 @@ TODO: merge upstream tests/misc/unexpand.pl | 39 ++ tests/misc/uniq.pl | 55 +++ tests/pr/pr-tests.pl | 49 +++ - 17 files changed, 2290 insertions(+), 154 deletions(-) + 17 files changed, 2291 insertions(+), 154 deletions(-) create mode 100755 tests/i18n/sort.sh create mode 100755 tests/misc/sort-mb-tests.sh diff --git a/lib/linebuffer.h b/lib/linebuffer.h -index 64181af..9b8fe5a 100644 +index b19fea70f..1f0a1a25d 100644 --- a/lib/linebuffer.h +++ b/lib/linebuffer.h @@ -21,6 +21,11 @@ @@ -53,7 +53,7 @@ index 64181af..9b8fe5a 100644 /* Initialize linebuffer LINEBUFFER for use. */ diff --git a/src/fold.c b/src/fold.c -index 8cd0d6b..d23edd5 100644 +index 2221f7207..a601f897b 100644 --- a/src/fold.c +++ b/src/fold.c @@ -22,12 +22,34 @@ @@ -209,10 +209,10 @@ index 8cd0d6b..d23edd5 100644 - saved_errno = errno; + *saved_errno = errno; - - if (offset_out) - fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); - ++ ++ if (offset_out) ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); ++ +} + +#if HAVE_MBRTOWC @@ -385,10 +385,10 @@ index 8cd0d6b..d23edd5 100644 + } + + *saved_errno = errno; -+ -+ if (offset_out) -+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); -+ + + if (offset_out) + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); + +} +#endif + @@ -427,7 +427,7 @@ index 8cd0d6b..d23edd5 100644 if (ferror (istream)) { error (0, saved_errno, "%s", quotef (filename)); -@@ -252,7 +499,8 @@ main (int argc, char **argv) +@@ -252,7 +500,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -437,7 +437,7 @@ index 8cd0d6b..d23edd5 100644 while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -261,7 +509,15 @@ main (int argc, char **argv) +@@ -261,7 +510,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -455,7 +455,7 @@ index 8cd0d6b..d23edd5 100644 case 's': /* Break at word boundaries. */ diff --git a/src/join.c b/src/join.c -index 98b461c..9990f38 100644 +index 1accfd48d..e27243f87 100644 --- a/src/join.c +++ b/src/join.c @@ -22,19 +22,33 @@ @@ -948,7 +948,7 @@ index 98b461c..9990f38 100644 break; diff --git a/src/pr.c b/src/pr.c -index 26f221f..633f50e 100644 +index 160608276..6374a7fb4 100644 --- a/src/pr.c +++ b/src/pr.c @@ -311,6 +311,24 @@ @@ -1714,7 +1714,7 @@ index 26f221f..633f50e 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 6d2eec5..f189a0d 100644 +index a78dbf713..57152ce3d 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -1971,7 +1971,7 @@ index 6d2eec5..f189a0d 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1648,11 +1797,70 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1652,11 +1801,70 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2043,7 +2043,7 @@ index 6d2eec5..f189a0d 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1667,10 +1875,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1671,10 +1879,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -2056,7 +2056,7 @@ index 6d2eec5..f189a0d 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1716,10 +1924,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1720,10 +1928,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2069,7 +2069,7 @@ index 6d2eec5..f189a0d 100644 if (newlim) lim = newlim; } -@@ -1750,6 +1958,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1758,6 +1966,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2200,7 +2200,7 @@ index 6d2eec5..f189a0d 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1836,8 +2168,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1844,8 +2176,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -2225,7 +2225,7 @@ index 6d2eec5..f189a0d 100644 line->keybeg = line_start; } } -@@ -1987,7 +2333,7 @@ human_numcompare (char const *a, char const *b) +@@ -1995,7 +2341,7 @@ human_numcompare (char const *a, char const *b) hideously fast. */ static int @@ -2234,7 +2234,7 @@ index 6d2eec5..f189a0d 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -1997,6 +2343,25 @@ numcompare (char const *a, char const *b) +@@ -2005,6 +2351,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2260,7 +2260,7 @@ index 6d2eec5..f189a0d 100644 /* Work around a problem whereby the long double value returned by glibc's strtold ("NaN", ...) contains uninitialized bits: clear all bytes of A and B before calling strtold. FIXME: remove this function if -@@ -2047,7 +2412,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2055,7 +2420,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2269,7 +2269,7 @@ index 6d2eec5..f189a0d 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2323,15 +2688,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2331,15 +2696,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -2287,7 +2287,7 @@ index 6d2eec5..f189a0d 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2465,7 +2829,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2473,7 +2837,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2296,7 +2296,7 @@ index 6d2eec5..f189a0d 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2523,11 +2887,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2531,11 +2895,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -2385,7 +2385,7 @@ index 6d2eec5..f189a0d 100644 { struct keyfield *key = keylist; -@@ -2612,7 +3052,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2620,7 +3060,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -2394,7 +2394,7 @@ index 6d2eec5..f189a0d 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2728,6 +3168,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2736,6 +3176,211 @@ keycompare (struct line const *a, struct line const *b) return key->reverse ? -diff : diff; } @@ -2606,7 +2606,7 @@ index 6d2eec5..f189a0d 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2755,7 +3400,7 @@ compare (struct line const *a, struct line const *b) +@@ -2763,7 +3408,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -2615,7 +2615,7 @@ index 6d2eec5..f189a0d 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4145,6 +4790,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4153,6 +4798,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -2623,7 +2623,7 @@ index 6d2eec5..f189a0d 100644 break; case 'g': key->general_numeric = true; -@@ -4224,7 +4870,7 @@ main (int argc, char **argv) +@@ -4232,7 +4878,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -2632,7 +2632,7 @@ index 6d2eec5..f189a0d 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4245,6 +4891,29 @@ main (int argc, char **argv) +@@ -4253,6 +4899,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -2662,7 +2662,7 @@ index 6d2eec5..f189a0d 100644 have_read_stdin = false; inittables (); -@@ -4519,13 +5188,34 @@ main (int argc, char **argv) +@@ -4527,13 +5196,34 @@ main (int argc, char **argv) case 't': { @@ -2701,7 +2701,7 @@ index 6d2eec5..f189a0d 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4536,9 +5226,11 @@ main (int argc, char **argv) +@@ -4544,9 +5234,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -2715,7 +2715,7 @@ index 6d2eec5..f189a0d 100644 } break; -@@ -4767,12 +5459,10 @@ main (int argc, char **argv) +@@ -4775,12 +5467,10 @@ main (int argc, char **argv) sort (files, nfiles, outfile, nthreads); } @@ -2729,7 +2729,7 @@ index 6d2eec5..f189a0d 100644 if (have_read_stdin && fclose (stdin) == EOF) sort_die (_("close failed"), "-"); diff --git a/src/uniq.c b/src/uniq.c -index 87a0c93..9f755d9 100644 +index e0247579b..534231f6d 100644 --- a/src/uniq.c +++ b/src/uniq.c @@ -21,6 +21,17 @@ @@ -2895,7 +2895,7 @@ index 87a0c93..9f755d9 100644 check_chars = SIZE_MAX; diff --git a/tests/i18n/sort.sh b/tests/i18n/sort.sh new file mode 100755 -index 0000000..26c95de +index 000000000..26c95de9a --- /dev/null +++ b/tests/i18n/sort.sh @@ -0,0 +1,29 @@ @@ -2929,11 +2929,11 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 568944e..192f776 100644 +index 08c403d10..9e366ebed 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -369,6 +369,8 @@ all_tests = \ - tests/misc/sort-discrim.sh \ +@@ -372,6 +372,8 @@ all_tests = \ + tests/sort/sort-field-limit.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ + tests/misc/sort-mb-tests.sh \ @@ -2942,7 +2942,7 @@ index 568944e..192f776 100644 tests/misc/sort-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl -index 8a9cad1..9293e39 100755 +index 8e5beaf61..040e321b2 100755 --- a/tests/misc/expand.pl +++ b/tests/misc/expand.pl @@ -27,6 +27,15 @@ my $prog = 'expand'; @@ -3009,7 +3009,7 @@ index 8a9cad1..9293e39 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index 7b192b4..76f073f 100755 +index 3a72629a3..af85ee54f 100755 --- a/tests/misc/fold.pl +++ b/tests/misc/fold.pl @@ -20,9 +20,18 @@ use strict; @@ -3082,7 +3082,7 @@ index 7b192b4..76f073f 100755 my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); exit $fail; diff --git a/tests/misc/join.pl b/tests/misc/join.pl -index 4d399d8..07f2823 100755 +index 8ab93ad75..bdd3bc731 100755 --- a/tests/misc/join.pl +++ b/tests/misc/join.pl @@ -25,6 +25,15 @@ my $limits = getlimits (); @@ -3153,7 +3153,7 @@ index 4d399d8..07f2823 100755 diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh new file mode 100755 -index 0000000..11836ba +index 000000000..11836baa5 --- /dev/null +++ b/tests/misc/sort-mb-tests.sh @@ -0,0 +1,45 @@ @@ -3203,7 +3203,7 @@ index 0000000..11836ba + +Exit $fail diff --git a/tests/misc/sort-merge.pl b/tests/misc/sort-merge.pl -index 23f6ed2..402a987 100755 +index 3a485803b..4540d2f84 100755 --- a/tests/misc/sort-merge.pl +++ b/tests/misc/sort-merge.pl @@ -26,6 +26,15 @@ my $prog = 'sort'; @@ -3263,7 +3263,7 @@ index 23f6ed2..402a987 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/sort.pl b/tests/misc/sort.pl -index c3e7f8e..6ecd3ff 100755 +index 081618d08..af217b49d 100755 --- a/tests/misc/sort.pl +++ b/tests/misc/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; @@ -3331,7 +3331,7 @@ index c3e7f8e..6ecd3ff 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index 6ba6d40..de86723 100755 +index c8f5ff918..518e82002 100755 --- a/tests/misc/unexpand.pl +++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); @@ -3388,7 +3388,7 @@ index 6ba6d40..de86723 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/uniq.pl b/tests/misc/uniq.pl -index f028036..8eaf59a 100755 +index 6f332c8a1..ce49925eb 100755 --- a/tests/misc/uniq.pl +++ b/tests/misc/uniq.pl @@ -23,9 +23,17 @@ my $limits = getlimits (); @@ -3464,7 +3464,7 @@ index f028036..8eaf59a 100755 @Tests = triple_test \@Tests; diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl -index ec3980a..136657d 100755 +index 272036997..8427f2b4a 100755 --- a/tests/pr/pr-tests.pl +++ b/tests/pr/pr-tests.pl @@ -24,6 +24,15 @@ use strict; @@ -3533,5 +3533,5 @@ index ec3980a..136657d 100755 my $verbose = $ENV{VERBOSE}; -- -2.7.4 +2.54.0 diff --git a/SPECS/coreutils.spec b/SPECS/coreutils.spec index 724c042..68ca9d5 100644 --- a/SPECS/coreutils.spec +++ b/SPECS/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 40%{?dist} +Release: 43%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -84,6 +84,14 @@ Patch23: coreutils-nproc-affinity-2.patch # fix sort fdlimit test failures on s390x with /dev/z90crypt (RHEL-60290) Patch24: coreutils-8.32-s390x-fdlimit.patch +# CVE-2025-5278 - Heap Buffer Under-Read in sort via Key Specification +# upstream commit: https://cgit.git.savannah.gnu.org/cgit/coreutils.git/commit/?id=8c9602e3a145e9596dc1a63c6ed67865814b6633 +Patch25: coreutils-CVE-2025-5278.patch + +# df: fix bug with automounted arguments (RHEL-180583) +# upstream commit: https://cgit.git.savannah.gnu.org/cgit/coreutils.git/commit/?id=a3c04f8da14f0fe2a0561bf5562032b8ce5dafa9 +Patch26: coreutils-8.32-df-fix-mishandled-automounts.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -333,6 +341,17 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Jun 10 2026 Lukáš Zaoral - 8.32-43 +- unexpand: fix heap overflow when a wide blank overshoots a tab stop (RHEL-182506) + +* Fri Jun 05 2026 Lukáš Zaoral - 8.32-42 +- CVE-2025-5278 - Fix Heap Buffer Under-Read in sort via Key Specification (RHEL-180332) +- unexpand: fix stack overflow with large tabsizes (RHEL-182506) +- df: fix bug with automounted arguments (RHEL-180583) + +* Sat Mar 21 2026 Lukáš Zaoral - 8.32-41 +- fix df/direct.sh and unexpand/mb.sh tests (RHEL-151534) + * Thu Jan 15 2026 Lukáš Zaoral - 8.32-40 - fold: fix processing of malformed UTF-8 sequences (RHEL-136086)