From e3c34cc523ee0b1c2c33abac395afb09ea762b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Fri, 5 Jun 2026 15:07:51 +0200 Subject: [PATCH] CVE-2025-5278 - Fix Heap Buffer Under-Read in sort via Key Specification Resolves: RHEL-180650 --- coreutils-CVE-2025-5278.patch | 149 ++++++++++++++++++++++++++++++++++ coreutils-i18n.patch | 119 ++++++++++++++------------- coreutils.spec | 6 ++ 3 files changed, 214 insertions(+), 60 deletions(-) create mode 100644 coreutils-CVE-2025-5278.patch diff --git a/coreutils-CVE-2025-5278.patch b/coreutils-CVE-2025-5278.patch new file mode 100644 index 0000000..efcca28 --- /dev/null +++ b/coreutils-CVE-2025-5278.patch @@ -0,0 +1,149 @@ +From c7a121c79a158dd7c0a26f403972cb167753a1de Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Sat, 3 Aug 2024 22:31:20 -0700 +Subject: [PATCH] shuf: fix randomness bug + +Problem reported by Daniel Carpenter . +* gl/lib/randread.c (randread_new): Fill the ISAAC buffer +instead of storing at most BYTES_BOUND bytes into it. + +(cherry picked from commit bfbb3ec7f798b179d7fa7b42673e068b18048899) +--- + lib/randread.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/lib/randread.c b/lib/randread.c +index cbee224b..43c0cf09 100644 +--- a/lib/randread.c ++++ b/lib/randread.c +@@ -189,9 +189,19 @@ randread_new (char const *name, size_t bytes_bound) + setvbuf (source, s->buf.c, _IOFBF, MIN (sizeof s->buf.c, bytes_bound)); + else + { ++ /* Fill the ISAAC buffer. Although it is tempting to read at ++ most BYTES_BOUND bytes, this is incorrect for two reasons. ++ First, BYTES_BOUND is just an estimate. ++ Second, even if the estimate is correct ++ ISAAC64 poorly randomizes when BYTES_BOUND is small ++ and just the first few bytes of s->buf.isaac.state.m ++ are random while the other bytes are all zero. See: ++ Aumasson J-P. On the pseudo-random generator ISAAC. ++ Cryptology ePrint Archive. 2006;438. ++ . */ + s->buf.isaac.buffered = 0; + if (! get_nonce (s->buf.isaac.state.m, +- MIN (sizeof s->buf.isaac.state.m, bytes_bound))) ++ sizeof s->buf.isaac.state.m)) + { + int e = errno; + randread_free_body (s); +-- +2.54.0 + +From 147a9bf745d1b99d2cf538194386ca4341574e8d 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 2d8324ca..09634197 100644 +--- a/src/sort.c ++++ b/src/sort.c +@@ -1644,7 +1644,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; + } +@@ -1746,7 +1750,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 fdbf3694..0b18ec9d 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -385,6 +385,7 @@ all_tests = \ + tests/sort/sort-debug-keys.sh \ + tests/sort/sort-debug-warn.sh \ + tests/sort/sort-discrim.sh \ ++ tests/sort/sort-field-limit.sh \ + tests/sort/sort-files0-from.pl \ + tests/sort/sort-float.sh \ + tests/sort/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 00000000..52d8e1d1 +--- /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/coreutils-i18n.patch b/coreutils-i18n.patch index 7366c43..2b4d656 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -47,7 +47,7 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index 126e1e8..b4ccebf 100644 +index 126e1e80..b4ccebf2 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -163,6 +163,8 @@ gnulib_modules=" @@ -60,7 +60,7 @@ index 126e1e8..b4ccebf 100644 mbrtoc32 mbrtowc diff --git a/configure.ac b/configure.ac -index 9cb6ee1..1131ce3 100644 +index 9cb6ee14..1131ce35 100644 --- a/configure.ac +++ b/configure.ac @@ -504,6 +504,12 @@ fi @@ -77,7 +77,7 @@ index 9cb6ee1..1131ce3 100644 if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ diff --git a/lib/linebuffer.h b/lib/linebuffer.h -index ae0d55d..5bf5350 100644 +index ae0d55dd..5bf53503 100644 --- a/lib/linebuffer.h +++ b/lib/linebuffer.h @@ -22,6 +22,11 @@ @@ -104,7 +104,7 @@ index ae0d55d..5bf5350 100644 /* Initialize linebuffer LINEBUFFER for use. */ diff --git a/lib/mbchar.c b/lib/mbchar.c new file mode 100644 -index 0000000..d94b7c3 +index 00000000..d94b7c33 --- /dev/null +++ b/lib/mbchar.c @@ -0,0 +1,23 @@ @@ -133,7 +133,7 @@ index 0000000..d94b7c3 +#include "mbchar.h" diff --git a/lib/mbchar.h b/lib/mbchar.h new file mode 100644 -index 0000000..c06ef11 +index 00000000..c06ef11b --- /dev/null +++ b/lib/mbchar.h @@ -0,0 +1,373 @@ @@ -512,7 +512,7 @@ index 0000000..c06ef11 +#endif /* _MBCHAR_H */ diff --git a/lib/mbfile.c b/lib/mbfile.c new file mode 100644 -index 0000000..8d2957b +index 00000000..8d2957b5 --- /dev/null +++ b/lib/mbfile.c @@ -0,0 +1,20 @@ @@ -538,7 +538,7 @@ index 0000000..8d2957b +#include "mbfile.h" diff --git a/lib/mbfile.h b/lib/mbfile.h new file mode 100644 -index 0000000..1ea1358 +index 00000000..1ea1358b --- /dev/null +++ b/lib/mbfile.h @@ -0,0 +1,261 @@ @@ -805,7 +805,7 @@ index 0000000..1ea1358 +#endif /* _MBFILE_H */ diff --git a/m4/mbchar.m4 b/m4/mbchar.m4 new file mode 100644 -index 0000000..471e8c4 +index 00000000..471e8c45 --- /dev/null +++ b/m4/mbchar.m4 @@ -0,0 +1,13 @@ @@ -824,7 +824,7 @@ index 0000000..471e8c4 +]) diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 new file mode 100644 -index 0000000..83068a9 +index 00000000..83068a99 --- /dev/null +++ b/m4/mbfile.m4 @@ -0,0 +1,14 @@ @@ -843,7 +843,7 @@ index 0000000..83068a9 + : +]) diff --git a/src/cut.c b/src/cut.c -index 061e09c..6d10425 100644 +index 061e09c3..6d104259 100644 --- a/src/cut.c +++ b/src/cut.c @@ -27,6 +27,11 @@ @@ -1503,7 +1503,7 @@ index 061e09c..6d10425 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index c95998d..d4386fe 100644 +index c95998dc..d4386fec 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -1635,7 +1635,7 @@ index c95998d..d4386fe 100644 to the list of tab stops. */ extern void diff --git a/src/expand-common.h b/src/expand-common.h -index 1a57108..6025652 100644 +index 1a57108e..60256522 100644 --- a/src/expand-common.h +++ b/src/expand-common.h @@ -25,6 +25,18 @@ extern size_t max_column_width; @@ -1658,7 +1658,7 @@ index 1a57108..6025652 100644 extern void add_tab_stop (uintmax_t tabval); diff --git a/src/expand.c b/src/expand.c -index a6176a9..60b1b8e 100644 +index a6176a97..60b1b8ee 100644 --- a/src/expand.c +++ b/src/expand.c @@ -38,6 +38,9 @@ @@ -1814,7 +1814,7 @@ index a6176a9..60b1b8e 100644 } diff --git a/src/fold.c b/src/fold.c -index 941ad11..2b11981 100644 +index 941ad11c..2b119815 100644 --- a/src/fold.c +++ b/src/fold.c @@ -23,10 +23,32 @@ @@ -2218,7 +2218,7 @@ index 941ad11..2b11981 100644 case 's': /* Break at word boundaries. */ diff --git a/src/local.mk b/src/local.mk -index 96ee941..8fdb8fc 100644 +index 96ee941c..8fdb8fc3 100644 --- a/src/local.mk +++ b/src/local.mk @@ -450,8 +450,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) @@ -2233,7 +2233,7 @@ index 96ee941..8fdb8fc 100644 src_wc_SOURCES = src/wc.c if USE_AVX2_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index 09c6fa8..7552b62 100644 +index 09c6fa8a..7552b629 100644 --- a/src/pr.c +++ b/src/pr.c @@ -312,6 +312,24 @@ @@ -3004,7 +3004,7 @@ index 09c6fa8..7552b62 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 2d8324c..46331b8 100644 +index 09634197..dea94575 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -3261,7 +3261,7 @@ index 2d8324c..46331b8 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1649,12 +1798,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1653,12 +1802,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3334,7 +3334,7 @@ index 2d8324c..46331b8 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1669,10 +1877,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1673,10 +1881,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. */ @@ -3347,7 +3347,7 @@ index 2d8324c..46331b8 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1718,10 +1926,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1722,10 +1930,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3360,7 +3360,7 @@ index 2d8324c..46331b8 100644 if (newlim) lim = newlim; } -@@ -1752,6 +1960,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1760,6 +1968,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3491,7 +3491,7 @@ index 2d8324c..46331b8 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 -@@ -1838,8 +2170,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1846,8 +2178,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3516,7 +3516,7 @@ index 2d8324c..46331b8 100644 line->keybeg = line_start; } } -@@ -1977,12 +2323,10 @@ find_unit_order (char const *number) +@@ -1985,12 +2331,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3532,7 +3532,7 @@ index 2d8324c..46331b8 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1994,7 +2338,7 @@ human_numcompare (char const *a, char const *b) +@@ -2002,7 +2346,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -3541,7 +3541,7 @@ index 2d8324c..46331b8 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2004,6 +2348,25 @@ numcompare (char const *a, char const *b) +@@ -2012,6 +2356,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3567,7 +3567,7 @@ index 2d8324c..46331b8 100644 static int nan_compare (long double a, long double b) { -@@ -2045,7 +2408,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2053,7 +2416,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3576,7 +3576,7 @@ index 2d8324c..46331b8 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2372,15 +2735,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2380,15 +2743,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3594,7 +3594,7 @@ index 2d8324c..46331b8 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2526,7 +2888,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2534,7 +2896,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 */ @@ -3603,7 +3603,7 @@ index 2d8324c..46331b8 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2574,9 +2936,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2582,9 +2944,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3616,7 +3616,7 @@ index 2d8324c..46331b8 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2587,9 +2949,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2595,9 +2957,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3629,7 +3629,7 @@ index 2d8324c..46331b8 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2597,19 +2959,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2605,19 +2967,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3653,7 +3653,7 @@ index 2d8324c..46331b8 100644 } } -@@ -2620,7 +2982,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2628,7 +2990,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) { error (0, 0, _("%snumbers use %s as a decimal point in this locale"), @@ -3662,7 +3662,7 @@ index 2d8324c..46331b8 100644 quote (((char []) {decimal_point, 0}))); } -@@ -2662,11 +3024,87 @@ diff_reversed (int diff, bool reversed) +@@ -2670,11 +3032,87 @@ diff_reversed (int diff, bool reversed) return reversed ? (diff < 0) - (diff > 0) : diff; } @@ -3751,7 +3751,7 @@ index 2d8324c..46331b8 100644 { struct keyfield *key = keylist; -@@ -2747,7 +3185,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2755,7 +3193,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3760,7 +3760,7 @@ index 2d8324c..46331b8 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2857,6 +3295,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2865,6 +3303,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -3972,7 +3972,7 @@ index 2d8324c..46331b8 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. */ -@@ -2884,7 +3527,7 @@ compare (struct line const *a, struct line const *b) +@@ -2892,7 +3535,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3981,7 +3981,7 @@ index 2d8324c..46331b8 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4272,6 +4915,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4280,6 +4923,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -3989,7 +3989,7 @@ index 2d8324c..46331b8 100644 break; case 'g': key->general_numeric = true; -@@ -4351,7 +4995,7 @@ main (int argc, char **argv) +@@ -4359,7 +5003,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3998,7 +3998,7 @@ index 2d8324c..46331b8 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4374,6 +5018,29 @@ main (int argc, char **argv) +@@ -4382,6 +5026,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4028,7 +4028,7 @@ index 2d8324c..46331b8 100644 have_read_stdin = false; inittables (); -@@ -4644,13 +5311,34 @@ main (int argc, char **argv) +@@ -4652,13 +5319,34 @@ main (int argc, char **argv) case 't': { @@ -4067,7 +4067,7 @@ index 2d8324c..46331b8 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4661,9 +5349,11 @@ main (int argc, char **argv) +@@ -4669,9 +5357,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4082,7 +4082,7 @@ index 2d8324c..46331b8 100644 break; diff --git a/src/unexpand.c b/src/unexpand.c -index aca67dd..f79c808 100644 +index aca67dd7..f79c8088 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -39,6 +39,9 @@ @@ -4287,7 +4287,7 @@ index aca67dd..f79c808 100644 } diff --git a/tests/Coreutils.pm b/tests/Coreutils.pm -index 18e7bea..24a141b 100644 +index 18e7bea8..24a141b1 100644 --- a/tests/Coreutils.pm +++ b/tests/Coreutils.pm @@ -269,6 +269,9 @@ sub run_tests ($$$$$) @@ -4302,7 +4302,7 @@ index 18e7bea..24a141b 100644 warn "$program_name: $test_name: test name is too long (> $max)\n"; diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh new file mode 100644 -index 0000000..6d6497a +index 00000000..6d6497a3 --- /dev/null +++ b/tests/expand/mb.sh @@ -0,0 +1,183 @@ @@ -4491,7 +4491,7 @@ index 0000000..6d6497a +Exit $fail diff --git a/tests/i18n/sort.sh b/tests/i18n/sort.sh new file mode 100644 -index 0000000..26c95de +index 00000000..26c95de9 --- /dev/null +++ b/tests/i18n/sort.sh @@ -0,0 +1,29 @@ @@ -4525,11 +4525,11 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index c213100..a828e7f 100644 +index d4546a0f..3bd74532 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -387,6 +387,8 @@ all_tests = \ - tests/sort/sort-discrim.sh \ +@@ -388,6 +388,8 @@ all_tests = \ + tests/sort/sort-field-limit.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ + tests/misc/sort-mb-tests.sh \ @@ -4537,7 +4537,7 @@ index c213100..a828e7f 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -591,6 +593,7 @@ all_tests = \ +@@ -592,6 +594,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4545,7 +4545,7 @@ index c213100..a828e7f 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -747,6 +750,7 @@ all_tests = \ +@@ -748,6 +751,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4554,7 +4554,7 @@ index c213100..a828e7f 100644 # See tests/factor/create-test.sh. diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl -index 11f3fc4..d609a2c 100755 +index 11f3fc4b..d609a2cb 100755 --- a/tests/misc/expand.pl +++ b/tests/misc/expand.pl @@ -27,6 +27,15 @@ my $prog = 'expand'; @@ -4621,7 +4621,7 @@ index 11f3fc4..d609a2c 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index 00b4362..7d51bea 100755 +index 00b43624..7d51bea5 100755 --- a/tests/misc/fold.pl +++ b/tests/misc/fold.pl @@ -20,9 +20,18 @@ use strict; @@ -4695,7 +4695,7 @@ index 00b4362..7d51bea 100755 exit $fail; diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh new file mode 100644 -index 0000000..11836ba +index 00000000..11836baa --- /dev/null +++ b/tests/misc/sort-mb-tests.sh @@ -0,0 +1,45 @@ @@ -4745,7 +4745,7 @@ index 0000000..11836ba + +Exit $fail diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index 76bcbd4..59eb819 100755 +index 76bcbd4d..59eb8199 100755 --- a/tests/misc/unexpand.pl +++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); @@ -4802,7 +4802,7 @@ index 76bcbd4..59eb819 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl -index 6b34e0b..34b4aeb 100755 +index 6b34e0b6..34b4aeb0 100755 --- a/tests/pr/pr-tests.pl +++ b/tests/pr/pr-tests.pl @@ -24,6 +24,15 @@ use strict; @@ -4871,7 +4871,7 @@ index 6b34e0b..34b4aeb 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort-merge.pl b/tests/sort/sort-merge.pl -index 89eed0c..b855d73 100755 +index 89eed0c6..b855d738 100755 --- a/tests/sort/sort-merge.pl +++ b/tests/sort/sort-merge.pl @@ -26,6 +26,15 @@ my $prog = 'sort'; @@ -4931,7 +4931,7 @@ index 89eed0c..b855d73 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort.pl b/tests/sort/sort.pl -index d49f65f..ebba925 100755 +index d49f65f6..ebba9255 100755 --- a/tests/sort/sort.pl +++ b/tests/sort/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; @@ -5000,7 +5000,7 @@ index d49f65f..ebba925 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh new file mode 100644 -index 0000000..f64542e +index 00000000..f64542eb --- /dev/null +++ b/tests/unexpand/mb.sh @@ -0,0 +1,173 @@ @@ -5178,5 +5178,4 @@ index 0000000..f64542e + +Exit $fail -- -2.53.0 - +2.54.0 diff --git a/coreutils.spec b/coreutils.spec index 7900fd7..01d4a4a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -41,6 +41,12 @@ Patch105: coreutils-9.5-ls-k-info-fix.patch Patch106: coreutils-nproc-affinity-1.patch Patch107: coreutils-nproc-affinity-2.patch +# CVE-2025-5278 - Heap Buffer Under-Read in sort via Key Specification +# upstream commits (first patch fixes an unitialized read uncovered by the CVE reproducer): +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/commit/?id=bfbb3ec7f798b179d7fa7b42673e068b18048899 +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/commit/?id=8c9602e3a145e9596dc1a63c6ed67865814b6633 +Patch108: coreutils-CVE-2025-5278.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch