From 9f135faa5cb4686c9f3a6f5facf9abd0b6cc6267 Mon Sep 17 00:00:00 2001 From: liuh Date: Fri, 1 Nov 2024 17:43:23 +0800 Subject: [PATCH] tail: avoid infloop with -c on /dev/zero --- ...ail-avoid-infloop-with-c-on-dev-zero.patch | 84 +++++++++++++++++++ coreutils.spec | 6 +- 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 backport-tail-avoid-infloop-with-c-on-dev-zero.patch diff --git a/backport-tail-avoid-infloop-with-c-on-dev-zero.patch b/backport-tail-avoid-infloop-with-c-on-dev-zero.patch new file mode 100644 index 0000000..6e8f62b --- /dev/null +++ b/backport-tail-avoid-infloop-with-c-on-dev-zero.patch @@ -0,0 +1,84 @@ +From fb543b6b82c1f3a20ff88f44cc3ed367bfe811b6 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Fri, 19 Apr 2024 21:44:32 -0700 +Subject: [PATCH] tail: avoid infloop with -c on /dev/zero + +Problem reported by Ionut Nicula in: +https://bugs.gnu.org/70477 +* src/tail.c (tail_bytes): Do not loop forever on commands +like 'tail -c 4096 /dev/zero'. +* tests/tail/tail-c.sh: Test this fix. +--- + src/tail.c | 24 +++++++++++++++++++----- + tests/tail/tail-c.sh | 10 ++++++++++ + 2 files changed, 29 insertions(+), 5 deletions(-) + +diff --git a/src/tail.c b/src/tail.c +index 52c0810..a3b46ca 100644 +--- a/src/tail.c ++++ b/src/tail.c +@@ -760,7 +760,8 @@ free_lbuffers: + return ok; + } + +-/* Print the last N_BYTES characters from the end of pipe FD. ++/* Print the last N_BYTES characters from the end of FD. ++ Work even if the input is a pipe. + This is a stripped down version of pipe_lines. + Return true if successful. */ + +@@ -1875,15 +1876,28 @@ tail_bytes (char const *pretty_filename, int fd, uintmax_t n_bytes, + { + off_t end_pos = -1; + off_t current_pos = -1; ++ bool copy_from_current_pos = false; + + if (! presume_input_pipe && n_bytes <= OFF_T_MAX) + { + if (usable_st_size (&stats)) +- end_pos = stats.st_size; +- else if ((current_pos = lseek (fd, -n_bytes, SEEK_END)) != -1) +- end_pos = current_pos + n_bytes; ++ { ++ /* Use st_size only if it's so large that this is ++ probably not a /proc or similar file, where st_size ++ is notional. */ ++ end_pos = stats.st_size; ++ off_t smallish_size = STP_BLKSIZE (&stats); ++ copy_from_current_pos = smallish_size < end_pos; ++ } ++ else ++ { ++ current_pos = lseek (fd, -n_bytes, SEEK_END); ++ copy_from_current_pos = current_pos != -1; ++ if (copy_from_current_pos) ++ end_pos = current_pos + n_bytes; ++ } + } +- if (end_pos <= (off_t) STP_BLKSIZE (&stats)) ++ if (! copy_from_current_pos) + return pipe_bytes (pretty_filename, fd, n_bytes, read_pos); + if (current_pos == -1) + current_pos = xlseek (fd, 0, SEEK_CUR, pretty_filename); +diff --git a/tests/tail/tail-c.sh b/tests/tail/tail-c.sh +index f518e5b..a9f2bc2 100755 +--- a/tests/tail/tail-c.sh ++++ b/tests/tail/tail-c.sh +@@ -35,4 +35,14 @@ printf '123456' | tail -c3 > out || fail=1 + printf '456' > exp || framework_failure_ + compare exp out || fail=1 + ++# Any part of /dev/zero should be valid for tail -c. ++head -c 4096 /dev/zero >exp || fail=1 ++tail -c 4096 /dev/zero >out || fail=1 ++compare exp out || fail=1 ++ ++# Any part of /dev/urandom, if it exists, should be valid for tail -c. ++if test -r /dev/urandom; then ++ timeout --verbose 1 tail -c 4096 /dev/urandom >/dev/null || fail=1 ++fi ++ + Exit $fail +-- +2.43.0 + diff --git a/coreutils.spec b/coreutils.spec index 4d4f154..54dd300 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,6 +1,6 @@ Name: coreutils Version: 9.5 -Release: 5 +Release: 6 License: GPLv3+ Summary: A set of basic GNU tools commonly used in shell scripts Url: https://www.gnu.org/software/coreutils/ @@ -30,6 +30,7 @@ patch15: backport-head-off_t-not-uintmax_t-for-file-offset.patch patch16: backport-shuf-avoid-integer-overflow-on-huge-inputs.patch patch17: backport-shuf-fix-randomness-bug.patch patch18: backport-chroot-whoami-use-uintmax_t-for-printing-uids.patch +patch19: backport-tail-avoid-infloop-with-c-on-dev-zero.patch Patch9001: coreutils-9.5-sw.patch @@ -159,6 +160,9 @@ popd %{_mandir}/man*/* %changelog +* Fri Nov 1 2024 liuh - 9.5-6 +- backport: tail: avoid infloop with -c on /dev/zero + * Fri Oct 25 2024 zhangyaqi - 9.5-5 - chroot,whoami: use uintmax_t for printing uids -- Gitee