dd: improve integer overflow checking

* src/dd.c: Prefer signed to unsigned types where either will do,
as this helps improve checking with gcc -fsanitize=undefined.
Limit the signed types to their intended ranges.
(MAX_BLOCKSIZE): Don’t exceed IDX_MAX - slop either.
(input_offset_overflow): Remove; overflow now denoted by negative.
(parse_integer): Return INTMAX_MAX on overflow, instead of unspecified.
Do not falsely report overflow for ‘00x99999999999999999999999999999’.
* tests/dd/misc.sh: New test for 00xBIG.
* tests/dd/skip-seek-past-file.sh: Adjust to new diagnostic wording.
New test for BIGxBIG.
This commit is contained in:
Paul Eggert
2022-01-18 13:22:02 -08:00
parent e462d928b0
commit e94d95075d
3 changed files with 179 additions and 141 deletions

View File

@@ -19,6 +19,7 @@
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
print_ver_ dd
export LC_ALL=C
tmp_in=dd-in
tmp_in2=dd-in2
@@ -98,7 +99,7 @@ test "$outbytes" -eq 3 || fail=1
# A delay is required to trigger a failure.
# There might be some missed failures but it's unlikely.
(echo a; sleep .1; echo b) \
| env LC_ALL=C dd bs=4 status=noxfer iflag=fullblock >out 2>err || fail=1
| dd bs=4 status=noxfer iflag=fullblock >out 2>err || fail=1
printf 'a\nb\n' > out_ok || framework_failure_
echo "1+0 records in
1+0 records out" > err_ok || framework_failure_
@@ -116,5 +117,11 @@ dd: warning: '0x' is a zero multiplier; use '00x' if that is intended
EOF
compare exp err || fail=1
echo "0+0 records in
0+0 records out" >err_ok || framework_failure_
big=9999999999999999999999999999999999999999999999999999999999999
dd if=$tmp_in of=$tmp_out count=00x$big status=noxfer 2>err || fail=1
compare /dev/null $tmp_out || fail=1
compare err_ok err || fail=1
Exit $fail

View File

@@ -20,7 +20,7 @@
print_ver_ dd
require_sparse_support_ # for 'truncate --size=$OFF_T_MAX'
eval $(getlimits) # for OFF_T limits
export LC_ALL=C
printf "1234" > file || framework_failure_
@@ -65,8 +65,11 @@ compare err_ok err || fail=1
# skipping > OFF_T_MAX should fail immediately
dd bs=1 skip=$OFF_T_OFLOW count=0 status=noxfer < file 2> err && fail=1
# error message should be "... cannot skip: strerror(EOVERFLOW)"
grep "cannot skip:" err >/dev/null || fail=1
# error message should be "... invalid number: strerror(EOVERFLOW)"
grep "invalid number:" err >/dev/null || fail=1
dd bs=1 skip=${OFF_T_OFLOW}x$OFF_T_OFLOW count=0 status=noxfer < file 2> err &&
fail=1
grep "invalid number:" err >/dev/null || fail=1
# skipping > max file size should fail immediately
if ! truncate --size=$OFF_T_MAX in 2>/dev/null; then