bug#79555: unexpand: heap-buffer-overflow

Pádraig Brady <[email protected]>
Newsgroups gmane.comp.gnu.core-utils.bugs
Message-ID <[email protected]>
On 02/10/2025 10:25, Frank Busse wrote:
> Hi,
> 
> 
> KLEE found another bug in Coreutils 9.8:
> 
> $ printf '\x00\x08\x08\t    ' | unexpand '-3t +/ +6,'
> 
> ASAN confirms:
> 
> ---
> ==516254==ERROR: heap-buffer-overflow
> WRITE of size 1 at 0x7bd06c1e01f3 thread T0
>      #0 0x55fbf2552614 in unexpand src/unexpand.c:195
>      #1 0x55fbf2552614 in main src/unexpand.c:316
> ...
> ---

I'll apply the attached later.Marking this as done.

thank you,
Padraig
unexpand-overflow.patch (text/x-patch, 3 KB)
From 82c24acf38619828e6c78f70c11de1d2317af8be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]>
Date: Thu, 2 Oct 2025 12:24:20 +0100
Subject: [PATCH] unexpand: fix heap buffer overflow with --tabs=[+/]NUM

* src/expand-common.c (set_max_column_width): Refactor function from ...
(add_tab_stop): ... here.
(set_extend_size): Call new function.
(set_increment_size): Likewise.
* NEWS: Mention the bug fix.
Fixes https://bugs.gnu.org/79555
---
 NEWS                   |  4 ++++
 src/expand-common.c    | 19 ++++++++++++++-----
 tests/misc/unexpand.pl |  4 ++++
 3 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/NEWS b/NEWS
index a19e3aed6..6a5d98ff1 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   Previously it may have output too few lines.
   [bug introduced in coreutils-9.8]
 
+  unexpand no longer induces a heap buffer overflow with --tabs
+  that use the GNU extension /NUM or +NUM formats.
+  [bug introduced in coreutils-8.28]
+
 ** Improvements
 
   wc -l now operates 10% faster on hosts that support AVX512 instructions.
diff --git a/src/expand-common.c b/src/expand-common.c
index ca2ad4d67..14dd804f9 100644
--- a/src/expand-common.c
+++ b/src/expand-common.c
@@ -70,6 +70,15 @@ static bool have_read_stdin = false;
 int exit_status = EXIT_SUCCESS;
 
 
+static void
+set_max_column_width (colno width)
+{
+  if (max_column_width < width)
+    {
+      if (ckd_add (&max_column_width, width, 0))
+        error (EXIT_FAILURE, 0, _("tabs are too far apart"));
+    }
+}
 
 /* Add tab stop TABVAL to the end of 'tab_list'.  */
 extern void
@@ -82,11 +91,7 @@ add_tab_stop (colno tabval)
     tab_list = xpalloc (tab_list, &n_tabs_allocated, 1, -1, sizeof *tab_list);
   tab_list[first_free_tab++] = tabval;
 
-  if (max_column_width < column_width)
-    {
-      if (ckd_add (&max_column_width, column_width, 0))
-        error (EXIT_FAILURE, 0, _("tabs are too far apart"));
-    }
+  set_max_column_width (column_width);
 }
 
 static bool
@@ -103,6 +108,8 @@ set_extend_size (colno tabval)
     }
   extend_size = tabval;
 
+  set_max_column_width (extend_size);
+
   return ok;
 }
 
@@ -120,6 +127,8 @@ set_increment_size (colno tabval)
     }
   increment_size = tabval;
 
+  set_max_column_width (increment_size);
+
   return ok;
 }
 
diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl
index 27d9c17b6..bb7469cae 100755
--- a/tests/misc/unexpand.pl
+++ b/tests/misc/unexpand.pl
@@ -76,6 +76,10 @@ my @Tests =
      ['blanks-12', '-t', '3,4', {IN=> "01  4\n"}, {OUT=> "01\t\t4\n"}],
      ['blanks-13', '-t', '3,4', {IN=> "0   4\n"}, {OUT=> "0\t\t4\n"}],
 
+     # These would overflow a heap buffer from v8.28 - v9.8 inclusive
+     ['blanks-ext1', '-t', '3,+6', {IN=> "\t      "}, {OUT=> "\t\t"}],
+     ['blanks-ext2', '-t', '3,/9', {IN=> "\t      "}, {OUT=> "\t\t"}],
+
      # POSIX says spaces should only follow tabs. Also a single
      # trailing space is not converted to a tab, when before
      # a field starting with non blanks
-- 
2.51.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.