misc/186282: Buffer overrun in col utility
Rici Lake
ricilake at gmail.com
Thu Jan 30 17:30:00 UTC 2014
>Number: 186282
>Category: misc
>Synopsis: Buffer overrun in col utility
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Jan 30 17:30:00 UTC 2014
>Closed-Date:
>Last-Modified:
>Originator: Rici Lake
>Release: n/a (but the bug is present since forever)
>Organization:
>Environment:
>Description:
At line 78 of col.c (http://svnweb.freebsd.org/base/head/usr.bin/col/col.c), the c_column member of the CHAR struct is declared as short:
short c_column; /* column character is in */
This value is set (for each character) at line 299 from cur_col
c->c_column = cur_col;
But cur_col is an int.
Consequently, if the input has a line of more than 32768 characters, the assignment to c->c_column will produce an integer overflow, producing two errors: first, the value of c->column may become negative, which may cause random memory to be overwritten; second, it may limit the line's output size to 32768 characters, overlaying portions of the line over other portions.
The more serious issue, the buffer overrun, will be triggered in the case that l->l_needs_sort is set to true at line 306, which will happen if input characters are out of sequence as a result of backspaces in the input (more than one consecutive backspace is required to trigger this condition). In that case, control flow will eventually reach line 423:
count[c->c_column]++;
which may use a negative integer from c->c_column to index the malloc'd region count.
While this is not likely to be exploitable, since the memory overwrite is an increment rather than a set, it could certainly cause unpredictable behaviour. In addition, the integer overflow will cause other problems for input containing long lines.
>How-To-Repeat:
Simple demonstration:
valgrind col < <(printf 'xx\b\b'; printf z%.0s {1..131072}) | wc -c
>Fix:
A simple fix would be to change the declaration of c_column to int rather than short. However, this will only defer the integer overflow; it will still occur on lines of length greater than 2^31. In addition to the above, all increments to cur_col in the loop starting at line 174 should have integer overflow checks.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list