patch 9.1.0404: [security] xxd: buffer-overflow with specific flags

Problem:  [security] xxd: buffer-overflow with specific flags
Solution: Correctly calculate the required buffer space
          (Lennard Hofmann)

xxd writes each output line into a global buffer before printing.
The maximum size of that buffer was not calculated correctly.

This command was crashing in AddressSanitizer:
$ xxd -Ralways -g1 -c256 -d -o 9223372036854775808 /etc/passwd

This prints a line of 6680 bytes but the buffer only had room for 6549 bytes.
If the output from "-b" was colored, the line could be even longer.

closes: #14738

Co-authored-by: K.Takata <kentkt@csc.jp>
Signed-off-by: Lennard Hofmann <lennard.hofmann@web.de>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Lennard Hofmann
2024-05-10 14:17:26 +02:00
committed by Christian Brabandt
parent 8c35c26c1f
commit 67797191e0
5 changed files with 59 additions and 51 deletions

View File

@ -75,6 +75,9 @@ No maximum for \-ps. With \-ps, 0 results in one long line of output.
.IR \-C " | " \-capitalize .IR \-C " | " \-capitalize
Capitalize variable names in C include file style, when using \-i. Capitalize variable names in C include file style, when using \-i.
.TP .TP
.I \-d
show offset in decimal instead of hex.
.TP
.IR \-E " | " \-EBCDIC .IR \-E " | " \-EBCDIC
Change the character encoding in the righthand column from ASCII to EBCDIC. Change the character encoding in the righthand column from ASCII to EBCDIC.
This does not change the hexadecimal representation. The option is This does not change the hexadecimal representation. The option is
@ -138,12 +141,12 @@ anywhere. Use the combination
to read a bits dump instead of a hex dump. to read a bits dump instead of a hex dump.
.TP .TP
.IR \-R " " when .IR \-R " " when
In output the hex-value and the value are both colored with the same color In the output the hex-value and the value are both colored with the same color
depending on the hex-value. Mostly helping to differentiate printable and depending on the hex-value. Mostly helping to differentiate printable and
non-printable characters. non-printable characters.
.I \fIwhen\fP .I \fIwhen\fP
is is
.BR never ", " always ", or " auto . .BR never ", " always ", or " auto " (default: auto).
When the When the
.BR $NO_COLOR .BR $NO_COLOR
environment variable is set, colorization will be disabled. environment variable is set, colorization will be disabled.

View File

@ -49,6 +49,8 @@ OPTIONS
Capitalize variable names in C include file style, when using Capitalize variable names in C include file style, when using
-i. -i.
-d show offset in decimal instead of hex.
-E | -EBCDIC -E | -EBCDIC
Change the character encoding in the righthand column from ASCII Change the character encoding in the righthand column from ASCII
to EBCDIC. This does not change the hexadecimal representation. to EBCDIC. This does not change the hexadecimal representation.
@ -101,11 +103,11 @@ OPTIONS
instead of a hex dump. instead of a hex dump.
-R when -R when
In output the hex-value and the value are both colored with the In the output the hex-value and the value are both colored with
same color depending on the hex-value. Mostly helping to differ the same color depending on the hex-value. Mostly helping to
entiate printable and non-printable characters. when is never, differentiate printable and non-printable characters. when is
always, or auto. When the $NO_COLOR environment variable is never, always, or auto (default: auto). When the $NO_COLOR en
set, colorization will be disabled. vironment variable is set, colorization will be disabled.
-seek offset -seek offset
When used after -r: revert with <offset> added to file positions When used after -r: revert with <offset> added to file positions

View File

@ -411,6 +411,19 @@ func Test_xxd_max_cols()
endfor endfor
endfunc endfunc
" Try to trigger a buffer overflow (#14738)
func Test_xxd_buffer_overflow()
CheckUnix
new
let input = repeat('A', 256)
call writefile(['-9223372036854775808: ' . repeat("\e[1;32m41\e[0m ", 256) . ' ' . repeat("\e[1;32mA\e[0m", 256)], 'Xxdexpected', 'D')
exe 'r! printf ' . input . '| ' . s:xxd_cmd . ' -Ralways -g1 -c256 -d -o 9223372036854775808 > Xxdout'
call assert_equalfile('Xxdexpected', 'Xxdout')
call delete('Xxdout')
bwipe!
endfunc
" -c0 selects the format specific default column value, as if no -c was given " -c0 selects the format specific default column value, as if no -c was given
" except for -ps, where it disables extra newlines " except for -ps, where it disables extra newlines
func Test_xxd_c0_is_def_cols() func Test_xxd_c0_is_def_cols()

View File

@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
404,
/**/ /**/
403, 403,
/**/ /**/

View File

@ -62,6 +62,7 @@
* 17.01.2024 use size_t instead of usigned int for code-generation (-i), #13876 * 17.01.2024 use size_t instead of usigned int for code-generation (-i), #13876
* 25.01.2024 revert the previous patch (size_t instead of unsigned int) * 25.01.2024 revert the previous patch (size_t instead of unsigned int)
* 10.02.2024 fix buffer-overflow when writing color output to buffer, #14003 * 10.02.2024 fix buffer-overflow when writing color output to buffer, #14003
* 10.05.2024 fix another buffer-overflow when writing colored output to buffer, #14738
* *
* (c) 1990-1998 by Juergen Weigert (jnweiger@gmail.com) * (c) 1990-1998 by Juergen Weigert (jnweiger@gmail.com)
* *
@ -142,7 +143,7 @@ extern void perror __P((char *));
# endif # endif
#endif #endif
char version[] = "xxd 2024-02-10 by Juergen Weigert et al."; char version[] = "xxd 2024-05-10 by Juergen Weigert et al.";
#ifdef WIN32 #ifdef WIN32
char osver[] = " (Win32)"; char osver[] = " (Win32)";
#else #else
@ -205,29 +206,16 @@ char osver[] = "";
/* /*
* LLEN is the maximum length of a line; other than the visible characters * LLEN is the maximum length of a line; other than the visible characters
* we need to consider also the escape color sequence prologue/epilogue , * we need to consider also the escape color sequence prologue/epilogue ,
* (11 bytes for each character). The most larger format is the default one: * (11 bytes for each character).
* addr + 1 word for each col/2 + 1 char for each col
*
* addr 1st group 2nd group
* +-------+ +-----------------+ +------+
* 01234567: 1234 5678 9abc def0 12345678
*
* - addr: typically 012345678: -> from 10 up to 18 bytes (including trailing
* space)
* - 1st group: 1234 5678 9abc ... -> each byte may be colored, so add 11
* for each byte
* - space -> 1 byte
* - 2nd group: 12345678 -> each char may be colore so add 11
* for each byte
* - new line -> 1 byte
* - zero (end line) -> 1 byte
*/ */
#define LLEN (2*(int)sizeof(unsigned long) + 2 + /* addr + ": " */ \ #define LLEN \
(11 * 2 + 4 + 1) * (COLS / 2) + /* 1st group */ \ (39 /* addr: ⌈log10(ULONG_MAX)⌉ if "-d" flag given. We assume ULONG_MAX = 2**128 */ \
1 + /* space */ \ + 2 /* ": " */ \
(1 + 11) * COLS + /* 2nd group */ \ + 13 * COLS /* hex dump with colors */ \
1 + /* new line */ \ + (COLS - 1) /* whitespace between groups if "-g1" option given and "-c" maxed out */ \
1) /* zero */ + 2 /* whitespace */ \
+ 12 * COLS /* ASCII dump with colors */ \
+ 2) /* "\n\0" */
char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa; char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa;