Compare commits

...
Sign in to create a new pull request.

5 commits

Author SHA1 Message Date
Lukáš Zaoral
bce3e9cf2e
sort: fix buffer under-read
Resolves: CVE-2025-5278
Resolves: rhbz#2368766
2025-05-28 14:40:02 +02:00
Florian Weimer
0e4eadc2db Affinity mask handling in nproc for large CPU counts (rhbz#2325167) 2024-11-13 09:20:14 +01:00
Lukáš Zaoral
17ab55a583
fix fold -b with UTF8 locale
Fixes the following incorrect behaviour of fold caused by the i18n patch:
```
$ LC_ALL=en_US.UTF-8 fold -b -w6 <<<  $'1234567890\nabcdefghij\n1234567890\n'
123456
7890
a
bcdefg
hij
12
345678
90
```

Fixes: 97967f71c8 ("coreutils-i18n.patch: synchronize the patch with openSUSE")
Resolves: RHE L-60295
2024-09-27 13:29:25 +02:00
Lukáš Zaoral
91bb0a4297
tests: remove unmaintained STI tests 2024-08-26 13:01:38 +02:00
Lukáš Zaoral
6708c1b886
disable integration with systemd
Related: rhbz#2307847
2024-08-26 12:21:49 +02:00
12 changed files with 353 additions and 293 deletions

View file

@ -0,0 +1,107 @@
From 701a9bdbf78f869e0fb778ed5aede00e42517add Mon Sep 17 00:00:00 2001
From: Pádraig Brady <P@draigBrady.com>
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 b10183b..7af1a25 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 4da6756..642d225 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -388,6 +388,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 0000000..52d8e1d
--- /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 <https://www.gnu.org/licenses/>.
+
+. "${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.49.0

View file

@ -1,4 +1,4 @@
From 94cf02dfcb1be23dedf8a39af295f28ee2de6013 Mon Sep 17 00:00:00 2001 From 3ca26b2b340953a0193409c1153801775d61e352 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build> From: rpm-build <rpm-build>
Date: Wed, 30 Aug 2023 17:19:58 +0200 Date: Wed, 30 Aug 2023 17:19:58 +0200
Subject: [PATCH] coreutils-i18n.patch Subject: [PATCH] coreutils-i18n.patch
@ -17,7 +17,7 @@ Subject: [PATCH] coreutils-i18n.patch
src/expand-common.c | 114 ++++++ src/expand-common.c | 114 ++++++
src/expand-common.h | 12 + src/expand-common.h | 12 +
src/expand.c | 90 +++- src/expand.c | 90 +++-
src/fold.c | 312 ++++++++++++-- src/fold.c | 311 ++++++++++++--
src/local.mk | 4 +- src/local.mk | 4 +-
src/pr.c | 443 ++++++++++++++++++-- src/pr.c | 443 ++++++++++++++++++--
src/sort.c | 792 +++++++++++++++++++++++++++++++++--- src/sort.c | 792 +++++++++++++++++++++++++++++++++---
@ -34,7 +34,7 @@ Subject: [PATCH] coreutils-i18n.patch
tests/sort/sort-merge.pl | 42 ++ tests/sort/sort-merge.pl | 42 ++
tests/sort/sort.pl | 40 +- tests/sort/sort.pl | 40 +-
tests/unexpand/mb.sh | 172 ++++++++ tests/unexpand/mb.sh | 172 ++++++++
30 files changed, 3605 insertions(+), 196 deletions(-) 30 files changed, 3604 insertions(+), 196 deletions(-)
create mode 100644 lib/mbchar.c create mode 100644 lib/mbchar.c
create mode 100644 lib/mbchar.h create mode 100644 lib/mbchar.h
create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.c
@ -1820,7 +1820,7 @@ index a6176a9..60b1b8e 100644
} }
diff --git a/src/fold.c b/src/fold.c diff --git a/src/fold.c b/src/fold.c
index 941ad11..cf1e747 100644 index 941ad11..bdc466d 100644
--- a/src/fold.c --- a/src/fold.c
+++ b/src/fold.c +++ b/src/fold.c
@@ -23,10 +23,32 @@ @@ -23,10 +23,32 @@
@ -1968,7 +1968,7 @@ index 941ad11..cf1e747 100644
/* Look for the last blank. */ /* Look for the last blank. */
while (logical_end) while (logical_end)
{ {
@@ -214,13 +251,225 @@ fold_file (char const *filename, size_t width) @@ -214,13 +251,224 @@ fold_file (char const *filename, size_t width)
line_out[offset_out++] = c; line_out[offset_out++] = c;
} }
@ -2066,39 +2066,38 @@ index 941ad11..cf1e747 100644
+ } + }
+ +
+rescan: +rescan:
+ if (operating_mode == byte_mode) /* byte mode */ + if (convfail)
+ increment = 1;
+ else if (wc == L'\n')
+ {
+ /* preserve newline */
+ fwrite (line_out, sizeof(char), offset_out, stdout);
+ START_NEW_LINE;
+ continue;
+ }
+ else if (operating_mode == byte_mode) /* byte mode */
+ increment = mblength; + increment = mblength;
+ else if (operating_mode == character_mode) /* character mode */ + else if (operating_mode == character_mode) /* character mode */
+ increment = 1; + increment = 1;
+ else /* column mode */ + else /* column mode */
+ { + {
+ if (convfail) + switch (wc)
+ increment = 1;
+ else
+ { + {
+ switch (wc) + case L'\b':
+ { + increment = (column > 0) ? -1 : 0;
+ case L'\n': + break;
+ fwrite (line_out, sizeof(char), offset_out, stdout);
+ START_NEW_LINE;
+ continue;
+ +
+ case L'\b': + case L'\r':
+ increment = (column > 0) ? -1 : 0; + increment = -1 * column;
+ break; + break;
+ +
+ case L'\r': + case L'\t':
+ increment = -1 * column; + increment = 8 - column % 8;
+ break; + break;
+ +
+ case L'\t': + default:
+ increment = 8 - column % 8; + increment = wcwidth (wc);
+ break; + increment = (increment < 0) ? 0 : increment;
+
+ default:
+ increment = wcwidth (wc);
+ increment = (increment < 0) ? 0 : increment;
+ }
+ } + }
+ } + }
+ +
@ -2196,7 +2195,7 @@ index 941ad11..cf1e747 100644
if (STREQ (filename, "-")) if (STREQ (filename, "-"))
clearerr (istream); clearerr (istream);
else if (fclose (istream) != 0 && !saved_errno) else if (fclose (istream) != 0 && !saved_errno)
@@ -251,7 +500,8 @@ main (int argc, char **argv) @@ -251,7 +499,8 @@ main (int argc, char **argv)
atexit (close_stdout); atexit (close_stdout);
@ -2206,7 +2205,7 @@ index 941ad11..cf1e747 100644
while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1) while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1)
{ {
@@ -260,7 +510,15 @@ main (int argc, char **argv) @@ -260,7 +509,15 @@ main (int argc, char **argv)
switch (optc) switch (optc)
{ {
case 'b': /* Count bytes rather than columns. */ case 'b': /* Count bytes rather than columns. */
@ -3010,7 +3009,7 @@ index 09c6fa8..7552b62 100644
looking for more options and printing the next batch of files. looking for more options and printing the next batch of files.
diff --git a/src/sort.c b/src/sort.c diff --git a/src/sort.c b/src/sort.c
index 2d8324c..46331b8 100644 index 0963419..dea9457 100644
--- a/src/sort.c --- a/src/sort.c
+++ b/src/sort.c +++ b/src/sort.c
@@ -29,6 +29,14 @@ @@ -29,6 +29,14 @@
@ -3267,7 +3266,7 @@ index 2d8324c..46331b8 100644
++ptr; ++ptr;
if (ptr < lim) if (ptr < lim)
++ptr; ++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; return ptr;
} }
@ -3340,7 +3339,7 @@ index 2d8324c..46331b8 100644
{ {
char *ptr = line->text, *lim = ptr + line->length - 1; char *ptr = line->text, *lim = ptr + line->length - 1;
size_t eword = key->eword, echar = key->echar; 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. 'beginning' is the first character following the delimiting TAB.
Otherwise, leave PTR pointing at the first 'blank' character after Otherwise, leave PTR pointing at the first 'blank' character after
the preceding field. */ the preceding field. */
@ -3353,7 +3352,7 @@ index 2d8324c..46331b8 100644
++ptr; ++ptr;
if (ptr < lim && (eword || echar)) if (ptr < lim && (eword || echar))
++ptr; ++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. */ /* Make LIM point to the end of (one byte past) the current field. */
@ -3366,7 +3365,7 @@ index 2d8324c..46331b8 100644
if (newlim) if (newlim)
lim = 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; return ptr;
} }
@ -3497,7 +3496,7 @@ index 2d8324c..46331b8 100644
/* Fill BUF reading from FP, moving buf->left bytes from the end /* 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 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 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 else
{ {
if (key->skipsblanks) if (key->skipsblanks)
@ -3522,7 +3521,7 @@ index 2d8324c..46331b8 100644
line->keybeg = line_start; 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 ATTRIBUTE_PURE
static int static int
@ -3538,7 +3537,7 @@ index 2d8324c..46331b8 100644
int diff = find_unit_order (a) - find_unit_order (b); int diff = find_unit_order (a) - find_unit_order (b);
return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); 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 ATTRIBUTE_PURE
static int static int
@ -3547,7 +3546,7 @@ index 2d8324c..46331b8 100644
{ {
while (blanks[to_uchar (*a)]) while (blanks[to_uchar (*a)])
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); return strnumcmp (a, b, decimal_point, thousands_sep);
} }
@ -3573,7 +3572,7 @@ index 2d8324c..46331b8 100644
static int static int
nan_compare (long double a, long double b) 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. */ Return 0 if the name in S is not recognized. */
static int static int
@ -3582,7 +3581,7 @@ index 2d8324c..46331b8 100644
{ {
size_t lo = 0; size_t lo = 0;
size_t hi = MONTHS_PER_YEAR; 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; char saved = *lim;
*lim = '\0'; *lim = '\0';
@ -3600,7 +3599,7 @@ index 2d8324c..46331b8 100644
else if (key->general_numeric) else if (key->general_numeric)
ignore_value (strtold (beg, &tighter_lim)); ignore_value (strtold (beg, &tighter_lim));
else if (key->numeric || key->human_numeric) 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. */ /* Warn about significant leading blanks. */
bool implicit_skip = key_numeric (key) || key->month; bool implicit_skip = key_numeric (key) || key->month;
bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */
@ -3609,7 +3608,7 @@ index 2d8324c..46331b8 100644
&& ((!key->skipsblanks && !implicit_skip) && ((!key->skipsblanks && !implicit_skip)
|| (!key->skipsblanks && key->schar) || (!key->skipsblanks && key->schar)
|| (!key->skipeblanks && key->echar))) || (!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; bool number_locale_warned = false;
if (basic_numeric_field_span) if (basic_numeric_field_span)
{ {
@ -3622,7 +3621,7 @@ index 2d8324c..46331b8 100644
{ {
error (0, 0, error (0, 0,
_("field separator %s is treated as a " _("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) if (basic_numeric_field_span || general_numeric_field_span)
{ {
@ -3635,7 +3634,7 @@ index 2d8324c..46331b8 100644
{ {
error (0, 0, error (0, 0,
_("field separator %s is treated as a " _("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}))); quote (((char []) {decimal_point, 0})));
number_locale_warned = true; number_locale_warned = true;
} }
@ -3659,7 +3658,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, error (0, 0,
_("%snumbers use %s as a decimal point in this locale"), _("%snumbers use %s as a decimal point in this locale"),
@ -3668,7 +3667,7 @@ index 2d8324c..46331b8 100644
quote (((char []) {decimal_point, 0}))); 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; return reversed ? (diff < 0) - (diff > 0) : diff;
} }
@ -3757,7 +3756,7 @@ index 2d8324c..46331b8 100644
{ {
struct keyfield *key = keylist; 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) else if (key->human_numeric)
diff = human_numcompare (ta, tb); diff = human_numcompare (ta, tb);
else if (key->month) else if (key->month)
@ -3766,7 +3765,7 @@ index 2d8324c..46331b8 100644
else if (key->random) else if (key->random)
diff = compare_random (ta, tlena, tb, tlenb); diff = compare_random (ta, tlena, tb, tlenb);
else if (key->version) 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); return diff_reversed (diff, key->reverse);
} }
@ -3978,7 +3977,7 @@ index 2d8324c..46331b8 100644
/* Compare two lines A and B, returning negative, zero, or positive /* Compare two lines A and B, returning negative, zero, or positive
depending on whether A compares less than, equal to, or greater than B. */ 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); diff = - NONZERO (blen);
else if (blen == 0) else if (blen == 0)
diff = 1; diff = 1;
@ -3987,7 +3986,7 @@ index 2d8324c..46331b8 100644
{ {
/* xmemcoll0 is a performance enhancement as /* xmemcoll0 is a performance enhancement as
it will not unconditionally write '\0' after the 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; break;
case 'f': case 'f':
key->translate = fold_toupper; key->translate = fold_toupper;
@ -3995,7 +3994,7 @@ index 2d8324c..46331b8 100644
break; break;
case 'g': case 'g':
key->general_numeric = true; 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); initialize_exit_failure (SORT_FAILURE);
hard_LC_COLLATE = hard_locale (LC_COLLATE); hard_LC_COLLATE = hard_locale (LC_COLLATE);
@ -4004,7 +4003,7 @@ index 2d8324c..46331b8 100644
hard_LC_TIME = hard_locale (LC_TIME); hard_LC_TIME = hard_locale (LC_TIME);
#endif #endif
@@ -4374,6 +5018,29 @@ main (int argc, char **argv) @@ -4382,6 +5026,29 @@ main (int argc, char **argv)
thousands_sep = NON_CHAR; thousands_sep = NON_CHAR;
} }
@ -4034,7 +4033,7 @@ index 2d8324c..46331b8 100644
have_read_stdin = false; have_read_stdin = false;
inittables (); inittables ();
@@ -4644,13 +5311,34 @@ main (int argc, char **argv) @@ -4652,13 +5319,34 @@ main (int argc, char **argv)
case 't': case 't':
{ {
@ -4073,7 +4072,7 @@ index 2d8324c..46331b8 100644
else else
{ {
/* Provoke with 'sort -txx'. Complain about /* 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)); quote (optarg));
} }
} }
@ -4531,11 +4530,11 @@ index 0000000..26c95de
+ +
+Exit $fail +Exit $fail
diff --git a/tests/local.mk b/tests/local.mk diff --git a/tests/local.mk b/tests/local.mk
index fdbf369..a6ce49c 100644 index 0b18ec9..7c6d089 100644
--- a/tests/local.mk --- a/tests/local.mk
+++ b/tests/local.mk +++ b/tests/local.mk
@@ -387,6 +387,8 @@ all_tests = \ @@ -388,6 +388,8 @@ all_tests = \
tests/sort/sort-discrim.sh \ tests/sort/sort-field-limit.sh \
tests/sort/sort-files0-from.pl \ tests/sort/sort-files0-from.pl \
tests/sort/sort-float.sh \ tests/sort/sort-float.sh \
+ tests/misc/sort-mb-tests.sh \ + tests/misc/sort-mb-tests.sh \
@ -4543,7 +4542,7 @@ index fdbf369..a6ce49c 100644
tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-h-thousands-sep.sh \
tests/sort/sort-merge.pl \ tests/sort/sort-merge.pl \
tests/sort/sort-merge-fdlimit.sh \ tests/sort/sort-merge-fdlimit.sh \
@@ -590,6 +592,7 @@ all_tests = \ @@ -591,6 +593,7 @@ all_tests = \
tests/du/threshold.sh \ tests/du/threshold.sh \
tests/du/trailing-slash.sh \ tests/du/trailing-slash.sh \
tests/du/two-args.sh \ tests/du/two-args.sh \
@ -4551,7 +4550,7 @@ index fdbf369..a6ce49c 100644
tests/id/gnu-zero-uids.sh \ tests/id/gnu-zero-uids.sh \
tests/id/no-context.sh \ tests/id/no-context.sh \
tests/id/context.sh \ tests/id/context.sh \
@@ -746,6 +749,7 @@ all_tests = \ @@ -747,6 +750,7 @@ all_tests = \
tests/touch/read-only.sh \ tests/touch/read-only.sh \
tests/touch/relative.sh \ tests/touch/relative.sh \
tests/touch/trailing-slash.sh \ tests/touch/trailing-slash.sh \
@ -5183,5 +5182,5 @@ index 0000000..8a82d74
+LC_ALL=C unexpand in in > out || fail=1 +LC_ALL=C unexpand in in > out || fail=1
+compare exp out > /dev/null 2>&1 || fail=1 +compare exp out > /dev/null 2>&1 || fail=1
-- --
2.44.0 2.49.0

View file

@ -0,0 +1,55 @@
commit 45c2456a56337ebcafe0dd9faa2bd995ccbc3357
Author: Florian Weimer <fweimer@redhat.com>
Date: Mon Nov 11 14:05:53 2024 +0100
nproc: Use affinity mask even on systems with more than 1024 CPUs.
* lib/nproc.c (num_processors_via_affinity_mask): Retry
with larger affinity masks if CPU_ALLOC_SIZE is available.
diff --git a/lib/nproc.c b/lib/nproc.c
index 92a07e8289..48bc3d06fa 100644
--- a/lib/nproc.c
+++ b/lib/nproc.c
@@ -20,6 +20,7 @@
#include <config.h>
#include "nproc.h"
+#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <unistd.h>
@@ -124,6 +125,33 @@ num_processors_via_affinity_mask (void)
return count;
}
}
+#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \
+ && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */
+ {
+ unsigned int alloc_count = 1024;
+ while (1)
+ {
+ cpu_set_t *set = CPU_ALLOC (alloc_count);
+ if (set == NULL)
+ return 0;
+ unsigned int size = CPU_ALLOC_SIZE (alloc_count);
+ if (sched_getaffinity (0, size, set) == 0)
+ {
+ unsigned int count = CPU_COUNT_S (size, set);
+ CPU_FREE (set);
+ return count;
+ }
+ if (errno != EINVAL)
+ {
+ CPU_FREE (set);
+ return 0;
+ }
+ CPU_FREE (set);
+ alloc_count *= 2;
+ if (alloc_count == 0)
+ return 0;
+ }
+ }
#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */
{
cpu_set_t set;

View file

@ -0,0 +1,64 @@
commit ee0bc695303775da5026091a65e8ec2b764f4a26
Author: Bruno Haible <bruno@clisp.org>
Date: Mon Nov 11 15:40:52 2024 +0100
nproc: Use affinity mask even in out-of-memory situations.
* lib/nproc.c (num_processors_via_affinity_mask): Use a stack-allocated
cpu_set_t as fallback. Add comments.
diff --git a/lib/nproc.c b/lib/nproc.c
index 48bc3d06fa..0b5898d88f 100644
--- a/lib/nproc.c
+++ b/lib/nproc.c
@@ -125,15 +125,25 @@ num_processors_via_affinity_mask (void)
return count;
}
}
-#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \
- && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */
+#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */
+ /* There are two ways to use the sched_getaffinity() function:
+ - With a statically-sized cpu_set_t.
+ - With a dynamically-sized cpu_set_t.
+ Documentation:
+ <https://www.kernel.org/doc/man-pages/online/pages/man2/sched_getaffinity.2.html>
+ <https://www.kernel.org/doc/man-pages/online/pages/man3/CPU_SET.3.html>
+ The second way has the advantage that it works on systems with more than
+ 1024 CPUs. The first way has the advantage that it works also when memory
+ is tight. */
+# if defined CPU_ALLOC_SIZE /* glibc >= 2.6 */
{
unsigned int alloc_count = 1024;
- while (1)
+ for (;;)
{
cpu_set_t *set = CPU_ALLOC (alloc_count);
if (set == NULL)
- return 0;
+ /* Out of memory. */
+ break;
unsigned int size = CPU_ALLOC_SIZE (alloc_count);
if (sched_getaffinity (0, size, set) == 0)
{
@@ -143,16 +153,19 @@ num_processors_via_affinity_mask (void)
}
if (errno != EINVAL)
{
+ /* Some other error. */
CPU_FREE (set);
return 0;
}
CPU_FREE (set);
+ /* Retry with some larger cpu_set_t. */
alloc_count *= 2;
if (alloc_count == 0)
+ /* Integer overflow. Avoid an endless loop. */
return 0;
}
}
-#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */
+# endif
{
cpu_set_t set;

View file

@ -0,0 +1,42 @@
From bfbb3ec7f798b179d7fa7b42673e068b18048899 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Sat, 3 Aug 2024 22:31:20 -0700
Subject: shuf: fix randomness bug
Problem reported by Daniel Carpenter <https://bugs.gnu.org/72445>.
* 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)
---
gl/lib/randread.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/lib/randread.c b/lib/randread.c
index cbee224bb..43c0cf09f 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.
+ <https://eprint.iacr.org/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.49.0

View file

@ -1,7 +1,7 @@
Summary: A set of basic GNU tools commonly used in shell scripts Summary: A set of basic GNU tools commonly used in shell scripts
Name: coreutils Name: coreutils
Version: 9.5 Version: 9.5
Release: 8%{?dist} Release: 12%{?dist}
# some used parts of gnulib are under various variants of LGPL # some used parts of gnulib are under various variants of LGPL
License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later
Url: https://www.gnu.org/software/coreutils/ Url: https://www.gnu.org/software/coreutils/
@ -32,6 +32,16 @@ Patch103: coreutils-python3.patch
# df --direct # df --direct
Patch104: coreutils-df-direct.patch Patch104: coreutils-df-direct.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2325167
Patch105: coreutils-nproc-affinity-1.patch
Patch106: coreutils-nproc-affinity-2.patch
# sort: fix buffer under-read (CVE-2025-5278)
# * CVE test prereq: https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=bfbb3ec7f798b179d7fa7b42673e068b18048899
# * CVE fix: https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=8c9602e3a145e9596dc1a63c6ed67865814b6633
Patch107: coreutils-prereq-CVE-2025-5278.patch
Patch108: coreutils-CVE-2025-5278.patch
# (sb) lin18nux/lsb compliance - multibyte functionality patch # (sb) lin18nux/lsb compliance - multibyte functionality patch
Patch800: coreutils-i18n.patch Patch800: coreutils-i18n.patch
@ -58,7 +68,6 @@ BuildRequires: libselinux-utils
BuildRequires: make BuildRequires: make
BuildRequires: openssl-devel BuildRequires: openssl-devel
BuildRequires: strace BuildRequires: strace
BuildRequires: systemd-devel
BuildRequires: texinfo BuildRequires: texinfo
# For gpg verification of source tarball # For gpg verification of source tarball
@ -187,7 +196,6 @@ for type in separate single; do
--cache-file=../config.cache \ --cache-file=../config.cache \
--enable-install-program=arch \ --enable-install-program=arch \
--enable-no-install-program=kill,uptime \ --enable-no-install-program=kill,uptime \
--enable-systemd \
--with-tty-group \ --with-tty-group \
DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : DEFAULT_POSIX2_VERSION=200112 alternative=199209 || :
%make_build all V=1 %make_build all V=1
@ -274,6 +282,18 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir
%license COPYING %license COPYING
%changelog %changelog
* Wed May 28 2025 Lukáš Zaoral <lzaoral@redhat.com> - 9.5-12
- sort: fix buffer under-read (CVE-2025-5278)
* Wed Nov 13 2024 Florian Weimer <fweimer@redhat.com> - 9.5-11
- Affinity mask handling in nproc for large CPU counts (rhbz#2325167)
* Fri Sep 27 2024 Lukáš Zaoral <lzaoral@redhat.com> - 9.5-10
- fix fold -b with UTF8 locale (RHEL-60295)
* Mon Aug 26 2024 Lukáš Zaoral <lzaoral@redhat.com> - 9.5-9
- disable integration with systemd (rhbz#2307847)
* Wed Aug 21 2024 Lukáš Zaoral <lzaoral@redhat.com> - 9.5-8 * Wed Aug 21 2024 Lukáš Zaoral <lzaoral@redhat.com> - 9.5-8
- add missing systemd-devel buildrequires - add missing systemd-devel buildrequires

View file

@ -1,63 +0,0 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/coreutils/readlink-cannot-handle-recursive-symlink s
# Description: Test for readlink cannot handle recursive symlinks
# Author: Jan Scotka <jscotka@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2010 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# 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, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/CoreOS/coreutils/readlink-cannot-handle-recursive-symlinks
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Jan Scotka <jscotka@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Test for readlink cannot handle recursive symlinks" >> $(METADATA)
@echo "Type: Sanity" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RunFor: coreutils" >> $(METADATA)
@echo "Requires: coreutils" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
rhts-lint $(METADATA)

View file

@ -1,54 +0,0 @@
PURPOSE of /CoreOS/coreutils/readlink-cannot-handle-recursive-symlinks
Description: Test for readlink cannot handle recursive symlinks
Author: Jan Scotka <jscotka@redhat.com>
Bug summary: readlink cannot handle recursive symlinks
Description:
Description of problem:
The readlink command fails with an error "Too many levels of symbolic links", even if there are only 2 levels.
The readlink command from RHEL 3 and RHEL 4 and from Fedora 11 all work fine.
Among other changes between RHEL 4 and RHEL 5, RHEL 5's coreutils added calls to cycle_check() in lib/canonicalize.c, but in upstream canonicalize.c (now in gnulib instead of coreutils), we see the comment:
/* Detect loops. We cannot use the cycle-check module here,
since it's actually possible to encounter the same symlink
more than once in a given traversal. However, encountering
the same symlink,NAME pair twice does indicate a loop. */
http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/canonicalize.c;h=4f348398fd69ae516396313d18ac294a4ca3dde3;hb=b653eda3ac4864de205419d9f41eec267cb89eeb#l262
The latest canonicalize.c uses seen_triple() instead of cycle_check().
Version-Release number of selected component (if applicable):
coreutils-5.97-19.el5
How reproducible:
every time
Steps to Reproduce:
1. Create a directory with a symlink to itself
mkdir /tmp/dir
cd /tmp/dir
ln -s ../dir dirlink
2. Run readlink using the 'dirlink' symlink recursively
readlink -v -f dirlink
readlink -v -f dirlink/dirlink
readlink -v -f dirlink/dirlink/dirlink
Actual results:
The first readlink command on just dirlink succeeds, but the 2nd and 3rd commands fail with
readlink: dirlink/dirlink: Too many levels of symbolic links
Expected results:
$ readlink -v -f dirlink
/tmp/dir
$ readlink -v -f dirlink/dirlink
/tmp/dir
$ readlink -v -f dirlink/dirlink/dirlink
/tmp/dir
Additional info:

View file

@ -1,60 +0,0 @@
#!/bin/bash
# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /CoreOS/coreutils/readlink-cannot-handle-recursive-symlinks
# Description: Test for readlink cannot handle recursive symlinks
# Author: Jan Scotka <jscotka@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2010 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# 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, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Include rhts environment
. /usr/bin/rhts-environment.sh
. /usr/lib/beakerlib/beakerlib.sh
PACKAGE="coreutils"
rlJournalStart
rlPhaseStartSetup
rlAssertRpm $PACKAGE
rlRun "TmpDir=\`mktemp -d\`" 0 "Creating tmp directory"
rlRun "pushd $TmpDir"
rlRun "mkdir link" 0 "Creating test directory"
rlRun "cd link" 0 "cd to this dir"
rlRun "ln -s ../link link" 0 "creating symlink to ../link -> link"
rlPhaseEnd
rlPhaseStartTest
rlLog "Test of readlink up to 20 iteration"
export TMPVAR="link"
for foo in `seq 20`
do echo $TMPVAR
rlRun "readlink -v -f $TMPVAR" 0 "readlink of $TMPVAR"
TMPVAR="$TMPVAR/link"
done
rlPhaseEnd
rlPhaseStartCleanup
rlRun "popd"
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

View file

@ -1,39 +0,0 @@
#!/bin/sh
# Checks that touch ls rm and foo work
# https://www.mankier.com/1/beakerlib#Examples
. /usr/share/beakerlib/beakerlib.sh
# Set the full test name
TEST="/examples/beakerlib/Sanity/phases"
# Package being tested
PACKAGE="coreutils"
rlJournalStart
# Setup phase: Prepare test directory
rlPhaseStartSetup
rlAssertRpm $PACKAGE
rlRun 'TmpDir=$(mktemp -d)' 0 'Creating tmp directory' # no-reboot
rlRun "pushd $TmpDir"
rlPhaseEnd
# Test phase: Testing touch, ls and rm commands
rlPhaseStartTest
rlRun "touch foo" 0 "Creating the foo test file"
rlAssertExists "foo"
rlRun "ls -l foo" 0 "Listing the foo test file"
rlRun "rm foo" 0 "Removing the foo test file"
rlAssertNotExists "foo"
rlRun "ls -l foo" 2 "Listing foo should now report an error"
rlPhaseEnd
# Cleanup phase: Remove test directory
rlPhaseStartCleanup
rlRun "popd"
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
rlPhaseEnd
rlJournalEnd
# Print the test report
rlJournalPrintText

View file

@ -1,9 +0,0 @@
---
# This first play always runs on the local staging system
- hosts: localhost
tags:
- atomic
- classic
- container
roles:
- { role: standard-test-beakerlib, tests: [ test-basics, readlink-cannot-handle-recursive-symlinks ] }

View file

@ -1,2 +0,0 @@
# Fedora Continuous Integration: https://fedoraproject.org/wiki/CI
- include: test_basics.yml