Skip to content

col: fix cur_col underflow on backspace over a wide char#4464

Open
aizu-m wants to merge 1 commit into
util-linux:masterfrom
aizu-m:col-cur-col-underflow
Open

col: fix cur_col underflow on backspace over a wide char#4464
aizu-m wants to merge 1 commit into
util-linux:masterfrom
aizu-m:col-cur-col-underflow

Conversation

@aizu-m

@aizu-m aizu-m commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

AddressSanitizer, feeding col a small crafted stream under a UTF-8 locale:

==ERROR: AddressSanitizer: negative-size-param: (size=-7)
    #2 flush_line col.c:249
    #3 flush_lines col.c:383
    #4 main col.c:700

Tracked it back to the BS branch in handle_not_graphic(). cur_col is a
size_t and the only guard there is cur_col == 0. Give it a double-width
glyph, then CR, one space, then BS: the last stored character still has
c_width 2 while cur_col has dropped to 1, so cur_col -= 2 wraps to
SIZE_MAX. That value then lands in l_max_col and the stored c_column, and
flush_line() sizes count[] as l_max_col + 1 (which wraps to 0) before it
memsets and indexes the array, so the write runs off the end.

Reproducer under a UTF-8 locale:

printf '\xef\xbc\xa1\r \bXY\n' | col

Clamp the subtraction to the column origin, matching the intent of the
existing cur_col == 0 check.

The BS handler in handle_not_graphic() subtracts the last stored
character's width from lns->cur_col (a size_t) and only guards against
cur_col == 0. When the last graphic character is double-width and the
column was reset by CR then advanced by a single space, cur_col is 1 and
cur_col -= 2 wraps to SIZE_MAX. That feeds l_max_col and the stored
c_column, so flush_line() sizes count[] as l_max_col + 1 (== 0) and then
memsets sizeof(size_t) * l_max_col bytes and indexes count[SIZE_MAX] --
an out-of-bounds write reachable from stdin under a UTF-8 locale. Clamp
the subtraction so the column cannot go below zero.

Signed-off-by: Aizal Khan <aizumusheer2@gmail.com>
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.

1 participant