From eb7b34b2dbc1b3d0c51c7be0e4261933d652a4a6 Mon Sep 17 00:00:00 2001 From: wjiang Date: Mon, 8 Sep 2025 10:45:18 +0800 Subject: [PATCH] fix xxd buffer overflow --- ...r-overflow-when-writing-color-output.patch | 94 ++++++ ...-buffer-overflow-with-specific-flags.patch | 279 ++++++++++++++++++ vim.spec | 10 +- 3 files changed, 382 insertions(+), 1 deletion(-) create mode 100644 backport-9.1.0094-xxd-buffer-overflow-when-writing-color-output.patch create mode 100644 backport-9.1.0404-xxd-buffer-overflow-with-specific-flags.patch diff --git a/backport-9.1.0094-xxd-buffer-overflow-when-writing-color-output.patch b/backport-9.1.0094-xxd-buffer-overflow-when-writing-color-output.patch new file mode 100644 index 0000000..9cebcaf --- /dev/null +++ b/backport-9.1.0094-xxd-buffer-overflow-when-writing-color-output.patch @@ -0,0 +1,94 @@ +From 00221487731ea1868c57259c7aa0eb713cd7ade7 Mon Sep 17 00:00:00 2001 +From: Goffredo Baroncelli +Date: Sat, 10 Feb 2024 13:31:06 +0100 +Subject: [PATCH] patch 9.1.0094: xxd: buffer-overflow when writing color + output + +Problem: xxd: buffer-overflow when writing color output +Solution: properly account for the color escape sequences and + adjust LLEN macro + (Goffredo Baroncelli) + +xxd: crash with higer number of column + +xxd writes the data into a buffer before printing. Unfortunately +the buffer doesn't consider the space consumed by the escape +sequences used to change the color of the character. + +BEFORE: +$ xxd -Ralways -c 256 /etc/passwd +Segmentation fault (core dumped) + +AFTER: +$ ./xxd -Ralways -c 256 /etc/passwd +00000000: 726f 6f74 3a78 3a30 3a30 3a72 6f6f 743a 2f72 [...] + +To solve this issue I had to increase the size of the buffer +considering for each byte of data 11 further characters for the +color escape sequence. + +closes: #14003 + +Signed-off-by: Goffredo Baroncelli +Signed-off-by: Christian Brabandt +--- + src/xxd/xxd.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +diff --git a/src/xxd/xxd.c b/src/xxd/xxd.c +index a5f5f04ade27d1..cf8b4ea6a0e2ac 100644 +--- a/src/xxd/xxd.c ++++ b/src/xxd/xxd.c +@@ -58,6 +58,7 @@ + * 20.06.2022 Permit setting the variable names used by -i by David Gow + * 31.08.2023 -R never/auto/always prints colored output + * 06.10.2023 enable -r -b to reverse bit dumps ++ * 10.02.2024 fix buffer-overflow when writing color output to buffer, #14003 + * + * (c) 1990-1998 by Juergen Weigert (jnweiger@gmail.com) + * +@@ -138,7 +139,7 @@ extern void perror __P((char *)); + # endif + #endif + +-char version[] = "xxd 2023-10-25 by Juergen Weigert et al."; ++char version[] = "xxd 2024-02-10 by Juergen Weigert et al."; + #ifdef WIN32 + char osver[] = " (Win32)"; + #else +@@ -197,7 +198,33 @@ char osver[] = ""; + + #define TRY_SEEK /* attempt to use lseek, or skip forward by reading */ + #define COLS 256 /* change here, if you ever need more columns */ +-#define LLEN ((2*(int)sizeof(unsigned long)) + 4 + (9*COLS-1) + COLS + 2) ++ ++/* ++ * LLEN is the maximum length of a line; other than the visible characters ++ * we need to consider also the escape color sequence prologue/epilogue , ++ * (11 bytes for each character). The most larger format is the default one: ++ * 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 + ": " */ \ ++ (11 * 2 + 4 + 1) * (COLS / 2) + /* 1st group */ \ ++ 1 + /* space */ \ ++ (1 + 11) * COLS + /* 2nd group */ \ ++ 1 + /* new line */ \ ++ 1) /* zero */ + + char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa; + + diff --git a/backport-9.1.0404-xxd-buffer-overflow-with-specific-flags.patch b/backport-9.1.0404-xxd-buffer-overflow-with-specific-flags.patch new file mode 100644 index 0000000..608e3f2 --- /dev/null +++ b/backport-9.1.0404-xxd-buffer-overflow-with-specific-flags.patch @@ -0,0 +1,279 @@ +From 67797191e039196128c69ba1538ccaf2a4711323 Mon Sep 17 00:00:00 2001 +From: Lennard Hofmann +Date: Fri, 10 May 2024 14:17:26 +0200 +Subject: [PATCH] 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 +Signed-off-by: Lennard Hofmann +Signed-off-by: Christian Brabandt +--- + runtime/doc/xxd.1 | 7 ++++-- + runtime/doc/xxd.man | 54 +++++++++++++++++++++------------------- + src/testdir/test_xxd.vim | 13 ++++++++++ + src/xxd/xxd.c | 34 ++++++++----------------- + 4 files changed, 57 insertions(+), 51 deletions(-) + +diff --git a/runtime/doc/xxd.1 b/runtime/doc/xxd.1 +index f5a7c658939f03..c76f89bb65adc8 100644 +--- a/runtime/doc/xxd.1 ++++ b/runtime/doc/xxd.1 +@@ -75,6 +75,9 @@ No maximum for \-ps. With \-ps, 0 results in one long line of output. + .IR \-C " | " \-capitalize + Capitalize variable names in C include file style, when using \-i. + .TP ++.I \-d ++show offset in decimal instead of hex. ++.TP + .IR \-E " | " \-EBCDIC + Change the character encoding in the righthand column from ASCII to EBCDIC. + 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. + .TP + .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 + non-printable characters. + .I \fIwhen\fP + is +-.BR never ", " always ", or " auto . ++.BR never ", " always ", or " auto " (default: auto). + When the + .BR $NO_COLOR + environment variable is set, colorization will be disabled. +diff --git a/runtime/doc/xxd.man b/runtime/doc/xxd.man +index 56b69b4341757b..b06971bd461023 100644 +--- a/runtime/doc/xxd.man ++++ b/runtime/doc/xxd.man +@@ -49,6 +49,8 @@ OPTIONS + Capitalize variable names in C include file style, when using + -i. + ++ -d show offset in decimal instead of hex. ++ + -E | -EBCDIC + Change the character encoding in the righthand column from ASCII + to EBCDIC. This does not change the hexadecimal representation. +@@ -97,15 +99,15 @@ OPTIONS + truncating it. Use the combination -r -p to read plain hexadeci‐ + mal dumps without line number information and without a particu‐ + lar column layout. Additional whitespace and line breaks are al‐ +- lowed anywhere. Use the combination -r -b to read a bits dump ++ lowed anywhere. Use the combination -r -b to read a bits dump + instead of a hex dump. + + -R when +- In output the hex-value and the value are both colored with the +- same color depending on the hex-value. Mostly helping to differ‐ +- entiate printable and non-printable characters. when is never, +- always, or auto. When the $NO_COLOR environment variable is +- set, colorization will be disabled. ++ 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 non-printable characters. when is ++ never, always, or auto (default: auto). When the $NO_COLOR en‐ ++ vironment variable is set, colorization will be disabled. + + -seek offset + When used after -r: revert with added to file positions +@@ -113,9 +115,9 @@ OPTIONS + + -s [+][-]seek + Start at bytes abs. (or rel.) infile offset. + indicates +- that the seek is relative to the current stdin file position ++ that the seek is relative to the current stdin file position + (meaningless when not reading from stdin). - indicates that the +- seek should be that many characters from the end of the input ++ seek should be that many characters from the end of the input + (or if combined with +: before the current stdin file position). + Without -s option, xxd starts at the current file position. + +@@ -125,20 +127,20 @@ OPTIONS + Show version string. + + CAVEATS +- xxd -r has some built-in magic while evaluating line number informa‐ +- tion. If the output file is seekable, then the line numbers at the +- start of each hex dump line may be out of order, lines may be missing, +- or overlapping. In these cases xxd will lseek(2) to the next position. +- If the output file is not seekable, only gaps are allowed, which will ++ xxd -r has some built-in magic while evaluating line number informa‐ ++ tion. If the output file is seekable, then the line numbers at the ++ start of each hex dump line may be out of order, lines may be missing, ++ or overlapping. In these cases xxd will lseek(2) to the next position. ++ If the output file is not seekable, only gaps are allowed, which will + be filled by null-bytes. + + xxd -r never generates parse errors. Garbage is silently skipped. + + When editing hex dumps, please note that xxd -r skips everything on the + input line after reading enough columns of hexadecimal data (see option +- -c). This also means that changes to the printable ASCII (or EBCDIC) ++ -c). This also means that changes to the printable ASCII (or EBCDIC) + columns are always ignored. Reverting a plain (or PostScript) style hex +- dump with xxd -r -p does not depend on the correct number of columns. ++ dump with xxd -r -p does not depend on the correct number of columns. + Here, anything that looks like a pair of hex digits is interpreted. + + Note the difference between +@@ -146,28 +148,28 @@ CAVEATS + and + % xxd -i < file + +- xxd -s +seek may be different from xxd -s seek, as lseek(2) is used to ++ xxd -s +seek may be different from xxd -s seek, as lseek(2) is used to + "rewind" input. A '+' makes a difference if the input source is stdin, +- and if stdin's file position is not at the start of the file by the +- time xxd is started and given its input. The following examples may ++ and if stdin's file position is not at the start of the file by the ++ time xxd is started and given its input. The following examples may + help to clarify (or further confuse!): + +- Rewind stdin before reading; needed because the `cat' has already read ++ Rewind stdin before reading; needed because the `cat' has already read + to the end of stdin. + % sh -c "cat > plain_copy; xxd -s 0 > hex_copy" < file + +- Hex dump from file position 0x480 (=1024+128) onwards. The `+' sign ++ Hex dump from file position 0x480 (=1024+128) onwards. The `+' sign + means "relative to the current position", thus the `128' adds to the 1k + where dd left off. +- % sh -c "dd of=plain_snippet bs=1k count=1; xxd -s +128 > hex_snippet" ++ % sh -c "dd of=plain_snippet bs=1k count=1; xxd -s +128 > hex_snippet" + < file + + Hex dump from file position 0x100 (=1024-768) onwards. + % sh -c "dd of=plain_snippet bs=1k count=1; xxd -s +-768 > hex_snippet" + < file + +- However, this is a rare situation and the use of `+' is rarely needed. +- The author prefers to monitor the effect of xxd with strace(1) or ++ However, this is a rare situation and the use of `+' is rarely needed. ++ The author prefers to monitor the effect of xxd with strace(1) or + truss(1), whenever -s is used. + + EXAMPLES +@@ -211,7 +213,7 @@ EXAMPLES + % xxd -s 0x36 -l 13 -c 13 xxd.1 + 0000036: 3235 7468 204d 6179 2031 3939 36 25th May 1996 + +- Create a 65537 byte file with all bytes 0x00, except for the last one ++ Create a 65537 byte file with all bytes 0x00, except for the last one + which is 'A' (hex 0x41). + % echo "010000: 41" | xxd -r > file + +@@ -222,11 +224,11 @@ EXAMPLES + 000fffc: 0000 0000 40 ....A + + Create a 1 byte file containing a single 'A' character. The number af‐ +- ter '-r -s' adds to the line numbers found in the file; in effect, the ++ ter '-r -s' adds to the line numbers found in the file; in effect, the + leading bytes are suppressed. + % echo "010000: 41" | xxd -r -s -0x10000 > file + +- Use xxd as a filter within an editor such as vim(1) to hex dump a re‐ ++ Use xxd as a filter within an editor such as vim(1) to hex dump a re‐ + gion marked between `a' and `z'. + :'a,'z!xxd + +diff --git a/src/testdir/test_xxd.vim b/src/testdir/test_xxd.vim +index 7a2771e0338945..642f5e709ee081 100644 +--- a/src/testdir/test_xxd.vim ++++ b/src/testdir/test_xxd.vim +@@ -411,6 +411,19 @@ func Test_xxd_max_cols() + endfor + 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 + " except for -ps, where it disables extra newlines + func Test_xxd_c0_is_def_cols() +diff --git a/src/xxd/xxd.c b/src/xxd/xxd.c +index cf8b4ea6a0e2ac..7a3d36a7fe9716 100644 +--- a/src/xxd/xxd.c ++++ b/src/xxd/xxd.c +@@ -59,6 +59,7 @@ + * 31.08.2023 -R never/auto/always prints colored output + * 06.10.2023 enable -r -b to reverse bit dumps + * 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) + * +@@ -139,7 +140,7 @@ extern void perror __P((char *)); + # 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 + char osver[] = " (Win32)"; + #else +@@ -202,29 +203,16 @@ char osver[] = ""; + /* + * LLEN is the maximum length of a line; other than the visible characters + * we need to consider also the escape color sequence prologue/epilogue , +- * (11 bytes for each character). The most larger format is the default one: +- * 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 ++ * (11 bytes for each character). + */ +-#define LLEN (2*(int)sizeof(unsigned long) + 2 + /* addr + ": " */ \ +- (11 * 2 + 4 + 1) * (COLS / 2) + /* 1st group */ \ +- 1 + /* space */ \ +- (1 + 11) * COLS + /* 2nd group */ \ +- 1 + /* new line */ \ +- 1) /* zero */ ++#define LLEN \ ++ (39 /* addr: ⌈log10(ULONG_MAX)⌉ if "-d" flag given. We assume ULONG_MAX = 2**128 */ \ ++ + 2 /* ": " */ \ ++ + 13 * COLS /* hex dump with colors */ \ ++ + (COLS - 1) /* whitespace between groups if "-g1" option given and "-c" maxed out */ \ ++ + 2 /* whitespace */ \ ++ + 12 * COLS /* ASCII dump with colors */ \ ++ + 2) /* "\n\0" */ + + char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa; + diff --git a/vim.spec b/vim.spec index f3ce75b..88c9e33 100644 --- a/vim.spec +++ b/vim.spec @@ -14,7 +14,7 @@ Name: vim Epoch: 2 Version: %{baseversion}.%{patchlevel} -Release: 21 +Release: 22 Summary: Vim is a highly configurable text editor for efficiently creating and changing any kind of text. License: Vim and MIT URL: http://www.vim.org @@ -72,6 +72,8 @@ Patch6037: backport-02-fix-a-few-problems-with-the-tar-plugin.patch Patch6038: backport-03-update-tar_vim-to-support-permissions.patch Patch6039: backport-04-fix-code-execution-with-tar_vim.patch Patch6040: backport-CVE-2025-53905.patch +Patch6041: backport-9.1.0094-xxd-buffer-overflow-when-writing-color-output.patch +Patch6042: backport-9.1.0404-xxd-buffer-overflow-with-specific-flags.patch Patch9000: bugfix-rm-modify-info-version.patch Patch9001: fix-CVE-2024-47814.patch @@ -482,6 +484,12 @@ LC_ALL=en_US.UTF-8 make -j1 test || echo "Warning: Please check tests." %{_mandir}/man1/evim.* %changelog +* Mon Sep 08 2025 wangjiang - 2:9.0.2092-22 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:fix xxd buffer overflow + * Thu Aug 21 2025 wangjiang - 2:9.0.2092-21 - Type:bugfix - ID:NA -- Gitee