ITADN

pr: arithmetic overflow (overflow-checks) on a huge `-N` line number or `-l` lines-per-page

#13734Closedleeewee 创建于 26 天前
U - pr
L
leeeweecommented
Two of pr's own numeric computations perform unchecked integer arithmetic on user-controlled option values: - `-n -N <huge>` — the running line number is seeded from `-N` and incremented with `line_num += 1`, which **overflows** (`attempt to add with overflow`). - `-l <huge>` — the page geometry computes `content_lines_per_page * columns` (with a small column count), which **overflows** (`attempt to multiply with overflow`). Both **panic under `-C overflow-checks`** (debug builds, or a release build with overflow-checks on) and abort (exit 134); in a default release build they wrap silently. ## Steps to reproduce ```console $ printf 'l1\nl2\nl3\n' > /tmp/pri $ pr -n -N 18446744073709551615 /tmp/pri thread 'main' panicked at src/uu/pr/src/pr.rs:1120:17: attempt to add with overflow $ echo $? 134 $ pr -l 9999999999999999999 -3 /tmp/pri thread 'main' panicked at src/uu/pr/src/pr.rs:1582:9: attempt to multiply with overflow $ echo $? 134 ``` ## GNU behavior GNU rejects the out-of-range value without a panic. ```console $ /usr/bin/pr -n -N 18446744073709551615 /tmp/pri ; /usr/bin/pr: '-N NUMBER' invalid starting line number: ‘18446744073709551615’: Value too large for defined data type $ echo $? 1 $ /usr/bin/pr -l 9999999999999999999 -3 /tmp/pri ; /usr/bin/pr: '-l PAGE_LENGTH' invalid number of lines: ‘9999999999999999999’: Value too large for defined data type $echo $? 1 ``` ## Root cause ```rust // src/uu/pr/src/pr.rs:1063 let mut line_num = get_start_line_number(options); // = -N value // src/uu/pr/src/pr.rs:1120 line_num += 1; // overflows when -N is near usize::MAX ``` **Page geometry (`pr.rs:1582`, sibling check at `:1406`):** lines-per-page (from `-l`) times the column count is multiplied unchecked — a huge `-l` overflows it even with the default small column count: ```rust // src/uu/pr/src/pr.rs:1579-1582 (lines_to_read_for_page) if opts.double_space { (content_lines_per_page / 2) * columns } else { content_lines_per_page * columns // :1582 — overflows for a huge -l * columns } // and the same product gates the layout at pr.rs:1406: // if !merge && (lines.len() < (content_lines_per_page * columns)) { ... } ``` (A huge value via the `-COLUMN`/`--column` short option also reaches this multiply, but that trigger is the already-filed #12996.)
关闭于 22 天前 0 条评论