Skip to content

dd: don't panic on huge count/skip/seek operands#12884

Open
mistaste wants to merge 1 commit into
uutils:mainfrom
mistaste:fix-dd-large-numeric-args
Open

dd: don't panic on huge count/skip/seek operands#12884
mistaste wants to merge 1 commit into
uutils:mainfrom
mistaste:fix-dd-large-numeric-args

Conversation

@mistaste

Copy link
Copy Markdown
Contributor

Summary

Fixes #12843, #12845, #12846, #12848.

A very large count=, skip=, seek=, iseek= or oseek= operand overflowed
an internal blocks * block_size multiplication and aborted the process:

$ dd if=a of=b count=177817277272177278
thread 'main' panicked at src/uu/dd/src/dd.rs: attempt to multiply with overflow
$ dd if=a of=b iseek=166727721627616621762772
thread 'main' panicked at src/uu/dd/src/dd.rs: attempt to multiply with overflow

Change

  • Num::to_bytes now uses saturating_mul, so an out-of-range block count
    saturates to u64::MAX and is caught by the existing > i64::MAX (intmax_t)
    limit checks for skip/seek instead of panicking.
  • The same i64::MAX limit is now also enforced for count, which previously
    had no check and overflowed later in calc_loop_bsize.

These operands now report a clean error, matching GNU:

$ dd count=177817277272177278
dd: invalid number: '...': Value too large for defined data type

Checks

  • New regression test test_large_numeric_operands_do_not_panic (covers count/skip/seek/iseek/oseek); existing dd tests still pass.
  • cargo fmt clean, cargo clippy -p uu_dd --all-targets clean.

A very large `count=`, `skip=`, `seek=`, `iseek=` or `oseek=` operand
overflowed an internal `blocks * block_size` multiplication and aborted the
process:

    $ dd if=a of=b count=177817277272177278
    thread 'main' panicked at src/uu/dd/src/dd.rs: attempt to multiply with overflow

`Num::to_bytes` now uses `saturating_mul`, so an out-of-range block count
saturates to `u64::MAX` and is caught by the existing `> i64::MAX` (intmax_t)
limit checks for `skip`/`seek` instead of panicking. The same `i64::MAX` limit
is now also enforced for `count`, which previously had no check and overflowed
later in `calc_loop_bsize`.

These operands now report a clean error, matching GNU:

    $ dd count=177817277272177278
    dd: invalid number: '...': Value too large for defined data type

Fixes uutils#12843
Fixes uutils#12845
Fixes uutils#12846
Fixes uutils#12848
@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

Skip an intermittent issue tests/cut/bounded-memory (fails in this run but passes in the 'main' branch)
Skip an intermittent issue tests/date/date-locale-hour (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/pr/bounded-memory (passes in this run but fails in the 'main' branch)
Note: The gnu test tests/env/env-signal-handler was skipped on 'main' but is now failing.

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.

bug(dd): when count= is a very large number it panics

1 participant