Skip to content

tail: don't panic on '-c -N' with a huge N - #14372

Open
harshasiddartha wants to merge 1 commit into
uutils:mainfrom
harshasiddartha:fix/tail-negative-bytes-seek-overflow
Open

tail: don't panic on '-c -N' with a huge N#14372
harshasiddartha wants to merge 1 commit into
uutils:mainfrom
harshasiddartha:fix/tail-negative-bytes-seek-overflow

Conversation

@harshasiddartha

Copy link
Copy Markdown
Contributor

Fixes #14353.

tail -c -9223372036854775808 FILE on a seekable file larger than the block size aborts with attempt to negate with overflow (exit 101) in a build with overflow checks, and wraps silently in a release build.

bounded_tail built the backwards seek offset for -c -N as -(*count as i64). count is a u64, so 2^63 casts to i64::MIN, and negating i64::MIN overflows.

I now convert the count with i64::try_from before negating it. A count that doesn't fit in an i64 reaches further back than any file can be long, so it falls into the branch the arm already had for an offset landing before the start of the file: seek to 0 and print the whole file. That matches what -c -N already does for any other N larger than the file.

Tested with a new test in tests/by-util/test_tail.rs that runs -c -9223372036854775808 against an 8 KiB file (larger than sane_blksize, so the seek path is taken) and expects the whole file back. It fails with exit 101 before the change and passes after. I also ran the rest of test_tail and cargo clippy -p uu_tail. Everything was run on macOS only; test_follow_detects_file_truncation is flaky here under load, but it fails the same way on an unmodified checkout.

`bounded_tail` computed the backwards seek offset for `-c -N` as
`-(count as i64)`. For N of 2^63 that cast yields `i64::MIN`, whose
negation overflows: a build with overflow checks aborts with exit 101,
and a release build wraps around and seeks to a bogus position.

Convert the count to an `i64` first and, when it does not fit, take the
existing path for an offset that lands before the start of the file.
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

GNU test failed: tests/dd/misc. tests/dd/misc is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/df/over-mount-device. tests/df/over-mount-device is passing on 'main'. Maybe you have to rebase?
Skip an intermittent issue tests/cut/bounded-memory (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/date/date-locale-hour (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/inotify-dir-recreate (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/cat/splice is no longer failing!
Congrats! The gnu test tests/cp/cp-a-selinux is no longer failing!
Congrats! The gnu test tests/cut/cut is no longer failing!
Congrats! The gnu test tests/cut/mb-non-utf8 is no longer failing!
Congrats! The gnu test tests/dd/partial-write is no longer failing!
Congrats! The gnu test tests/expand/mb is no longer failing!
Congrats! The gnu test tests/ls/stat-free-symlinks is no longer failing!
Congrats! The gnu test tests/misc/close-stdout is no longer failing!
Congrats! The gnu test tests/mktemp/write-error is no longer failing!
Congrats! The gnu test tests/mv/dir2dir is no longer failing!
Congrats! The gnu test tests/mv/mv-exchange is no longer failing!
Congrats! The gnu test tests/nl/multibyte is no longer failing!
Congrats! The gnu test tests/od/od-float is no longer failing!
Congrats! The gnu test tests/od/od-j is no longer failing!
Congrats! The gnu test tests/ptx/ptx-overrun is no longer failing!
Congrats! The gnu test tests/sort/sort-merge-fdlimit is no longer failing!
Congrats! The gnu test tests/unexpand/mb is no longer failing!
Note: The gnu test tests/dd/fail-ftruncate-fstat was skipped on 'main' but is now failing.

Comment thread src/uu/tail/src/tail.rs
Comment on lines +472 to +474
// A count above `i64::MAX` has no negative counterpart to seek by,
// and reaches further back than any file can be long, so treat it
// like any other offset landing before the start of the file.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you write this as one line?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tail: arithmetic overflow (overflow-checks) on -c -N with N = 2^63 (i64::MIN negate)

2 participants