From b9b68f0bb1f375beedec36dbda1646513e28f4d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= Date: Wed, 24 Jan 2024 15:49:10 +0100 Subject: [PATCH] Fix a heap buffer underread in set_buf_break() --- ...ap-buffer-underread-in-set_buf_break.patch | 119 ++++++++++++++++++ indent.spec | 9 +- 2 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 indent-2.2.13-Fix-a-heap-buffer-underread-in-set_buf_break.patch diff --git a/indent-2.2.13-Fix-a-heap-buffer-underread-in-set_buf_break.patch b/indent-2.2.13-Fix-a-heap-buffer-underread-in-set_buf_break.patch new file mode 100644 index 0000000..3866edf --- /dev/null +++ b/indent-2.2.13-Fix-a-heap-buffer-underread-in-set_buf_break.patch @@ -0,0 +1,119 @@ +From 32df891141689ed73499f4e60f64268957f1e3c2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= +Date: Wed, 24 Jan 2024 14:03:58 +0100 +Subject: [PATCH] Fix a heap buffer underread in set_buf_break() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If an opening parenthesis follows a comment with a text, a read from +an invalid address happens in set_buf_break(): + + $ printf '/*a*/()' | valgrind -- ./src/indent - -o /dev/null + ==28887== Memcheck, a memory error detector + ==28887== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. + ==28887== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info + ==28887== Command: ./src/indent - -o /dev/null + ==28887== + ==28887== Invalid read of size 2 + ==28887== at 0x409989: set_buf_break (output.c:319) + ==28887== by 0x401FE7: indent_main_loop (indent.c:640) + ==28887== by 0x4022A7: indent (indent.c:759) + ==28887== by 0x40294E: indent_single_file (indent.c:1004) + ==28887== by 0x402A1C: indent_all (indent.c:1042) + ==28887== by 0x402BD0: main (indent.c:1123) + ==28887== Address 0x4a5facc is 4 bytes before a block of size 16 alloc'd + ==28887== at 0x4849E60: calloc (vg_replace_malloc.c:1595) + ==28887== by 0x408B61: xmalloc (globs.c:42) + ==28887== by 0x40765E: init_parser (parse.c:73) + ==28887== by 0x402B1F: main (indent.c:1101) + +It happens when checking an indentation level of the outer scope by indexing +parser_state_tos->paren_indents[]: + + level = parser_state_tos->p_l_follow; + [...] + /* Did we just parse a bracket that will be put on the next line + * by this line break? */ + if ((*token == '(') || (*token == '[')) + --level; /* then don't take it into account */ + [...] + if (level == 0) { + } else { +→ if (parser_state_tos->paren_indents[level - 1] < 0) {...} + } + +The cause is a special case for moving opening parentheses and +brackets to a next line. If parser_state_tos->p_l_follow is zero +(like in the reproducer), the index evaluates to -2 and goes out of +range of the paren_indents array. + +This patch simply prevents from decreasing the index under zero when +formating the code. Maybe it leaves some piece of code unformated, but +it's safe. + +I checked all places where p_l_follow is set (it is only in +handletoken.c) and they corretly prevent from decrasing it under +zero. That keeps set_buf_break() in output.c as the culprit. + + + +Signed-off-by: Petr Písař +--- + regression/TEST | 2 +- + regression/input/comment-parent-heap-underread.c | 3 +++ + regression/standard/comment-parent-heap-underread.c | 5 +++++ + src/output.c | 2 +- + 4 files changed, 10 insertions(+), 2 deletions(-) + create mode 100644 regression/input/comment-parent-heap-underread.c + create mode 100644 regression/standard/comment-parent-heap-underread.c + +diff --git a/regression/TEST b/regression/TEST +index 7c07c2e..951b1a2 100755 +--- a/regression/TEST ++++ b/regression/TEST +@@ -40,7 +40,7 @@ BUGS="case-label.c one-line-1.c one-line-2.c one-line-3.c \ + macro.c enum.c elif.c nested.c wrapped-string.c minus_predecrement.c \ + bug-gnu-33364.c float-constant-suffix.c block-comments.c \ + no-forced-nl-in-block-init.c hexadecimal_float.c binary-constant.c \ +- comment-heap-overread.c" ++ comment-heap-overread.c comment-parent-heap-underread.c" + + INDENTSRC="args.c backup.h backup.c dirent_def.h globs.c indent.h \ + indent.c indent_globs.h io.c lexi.c memcpy.c parse.c pr_comment.c \ +diff --git a/regression/input/comment-parent-heap-underread.c b/regression/input/comment-parent-heap-underread.c +new file mode 100644 +index 0000000..68e13cf +--- /dev/null ++++ b/regression/input/comment-parent-heap-underread.c +@@ -0,0 +1,3 @@ ++void foo(void) { ++/*a*/(1); ++} +diff --git a/regression/standard/comment-parent-heap-underread.c b/regression/standard/comment-parent-heap-underread.c +new file mode 100644 +index 0000000..9a1c6e3 +--- /dev/null ++++ b/regression/standard/comment-parent-heap-underread.c +@@ -0,0 +1,5 @@ ++void ++foo (void) ++{ ++/*a*/ (1); ++} +diff --git a/src/output.c b/src/output.c +index ee01bcc..17eee6e 100644 +--- a/src/output.c ++++ b/src/output.c +@@ -290,7 +290,7 @@ void set_buf_break ( + /* Did we just parse a bracket that will be put on the next line + * by this line break? */ + +- if ((*token == '(') || (*token == '[')) ++ if (level > 0 && ((*token == '(') || (*token == '['))) + { + --level; /* then don't take it into account */ + } +-- +2.43.0 + diff --git a/indent.spec b/indent.spec index 4700f79..a10e52a 100644 --- a/indent.spec +++ b/indent.spec @@ -1,7 +1,7 @@ Summary: A GNU program for formatting C code Name: indent Version: 2.2.13 -Release: 4%{?dist} +Release: 5%{?dist} # COPYING: GPL-3.0 text # doc/indent.texi: Latex2e-translated-notice # (AND a subset of Latex2e WITH a texinfo-commented GPL clause; @@ -116,6 +116,10 @@ Patch1: indent-2.2.13-Fix-an-out-of-buffer-read-in-search_brace-lexi-on-an.p # Fix CVE-2023-40305 (a heap buffer overwrite in search_brace), bug #2231919, # in upstream after 2.2.13, Patch2: indent-2.2.13-Fix-a-heap-buffer-overwrite-in-search_brace-CVE-2023.patch +# Fix a heap buffer underread in set_buf_break(), bug #2259883, proposed to an +# upstream +# +Patch3: indent-2.2.13-Fix-a-heap-buffer-underread-in-set_buf_break.patch BuildRequires: autoconf2.7x >= 2.71 # autoconf-archive for unbundled ax_cc_for_build.m4 BuildRequires: autoconf-archive @@ -179,6 +183,9 @@ make check %{?_smp_mflags} %{_infodir}/indent.info* %changelog +* Wed Jan 24 2024 Petr Pisar - 2.2.13-5 +- Fix a heap buffer underread in set_buf_break() (bug #2259883) + * Wed Aug 16 2023 Petr Pisar - 2.2.13-4 - Fix a heap overread in search_brace/lexi - Fix CVE-2023-40305 (a heap buffer overwrite in search_brace) (bug #2231919)