The size of the buffer used for printf -v is tracked in an int but this
can overflow since the buffer can be built up by multiple vsnprintf(3)
calls, each of which can append up to INT_MAX bytes to the buffer:

    $ INT_MAX=$(getconf INT_MAX)
    $ printf -v VAR "%$((INT_MAX-1))s%$((INT_MAX-1))s"
    Bus error: 10

or when appending individual chars:

    $ printf -v VAR "%$((INT_MAX-1))sXXX"
    -bash: xrealloc: cannot allocate 18446744071562068032 bytes

The return value of vsnprintf(3) or printf(3) can be negative if, e.g.
the underlying write(2) call fails, or if a width or precision is out
of range.  Currently, this return value used unchecked as an offset
into vbuf:

    $ printf -v VAR "%.$((INT_MAX+1))s"
    heap-buffer-overflow builtins/printf.def:1253:15 in vbprintf

and added to the total when counting bytes written for the %n conversion
specifier:

    $ printf "%$((INT_MAX+1))s%n" "" N
    $ echo "$N"
    -1

Also, skip ferror(), fflush(), and clearerr() when running with the -v
flag.

Attachment: 0001-printf-more-error-handling.patch
Description: Binary data

Reply via email to