summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2016-11-27 13:00:35 +0000
committerPádraig Brady <P@draigBrady.com>2016-11-27 21:10:15 +0000
commit6f30a99fa537adb029283cf2ef03cb4419350e6c (patch)
treed41198f0dfa6f0001acf809ac4b1ecfcf518a37d
parent5c09e82b4f0227b957ba1a73695abe9b0a3fd78b (diff)
downloadcoreutils-6f30a99fa537adb029283cf2ef03cb4419350e6c.tar.xz
tail: fix uninitialized memory read when failing to read file
Reproduced under UBSAN with `tail -f <&-` giving: tail.c:2220:18: runtime error: load of value 190, which is not a valid value for type ‘_Bool' * src/tail.c (tail_file): Ensure f->ignore is initialized in all cases where we can't tail the specified file. * tests/tail-2/follow-stdin.sh: Add a test case which checks stderr has no UBSAN warnings. Fixes http://bugs.gnu.org/25041
-rw-r--r--src/tail.c4
-rwxr-xr-xtests/tail-2/follow-stdin.sh12
2 files changed, 14 insertions, 2 deletions
diff --git a/src/tail.c b/src/tail.c
index 5c75be08d..6bf1e77d0 100644
--- a/src/tail.c
+++ b/src/tail.c
@@ -1940,8 +1940,6 @@ tail_file (struct File_spec *f, uintmax_t n_units)
ok = false;
f->errnum = -1;
f->tailable = false;
- f->ignore = ! (reopen_inaccessible_files
- && follow_mode == Follow_name);
error (0, 0, _("%s: cannot follow end of this type of file%s"),
quotef (pretty_name (f)),
f->ignore ? _("; giving up on this name") : "");
@@ -1949,6 +1947,8 @@ tail_file (struct File_spec *f, uintmax_t n_units)
if (!ok)
{
+ f->ignore = ! (reopen_inaccessible_files
+ && follow_mode == Follow_name);
close_fd (fd, pretty_name (f));
f->fd = -1;
}
diff --git a/tests/tail-2/follow-stdin.sh b/tests/tail-2/follow-stdin.sh
index a2f180428..3d51f6006 100755
--- a/tests/tail-2/follow-stdin.sh
+++ b/tests/tail-2/follow-stdin.sh
@@ -50,4 +50,16 @@ for mode in '' '---disable-inotify'; do
cleanup_
done
+
+# Before coreutils-8.26 this would induce an UMR under UBSAN
+returns_ 1 timeout 10 tail -f - <&- 2>err || fail=1
+cat <<\EOF >exp || framework_failure_
+tail: cannot fstat 'standard input': Bad file descriptor
+tail: error reading 'standard input': Bad file descriptor
+tail: no files remaining
+tail: -: Bad file descriptor
+EOF
+compare exp err || fail=1
+
+
Exit $fail