On 02/04/2013 09:22 AM, Marcel Böhme wrote:
    Dear all,
    The current version of cut (after 6.12.2012) exposes a SEG_FAULT:
    $echo 123 | cut --output-del="." -b-1,999999999-
    How the commit introduces the bug:
    Earlier, memory of length eol_start_length was allocated for the array
    printable_field - if max_range_endpoint < eol_start_length. So the
    access at eol_start_length would succeed.
    Now, even if max_range_endpoint < eol_start_length, as long as
    max_range_endpoint > 0, just like before, memory of length
    max_range_endpoint is allocated for array printable_field which is
    accessed "out-of-bounds" at eol_start_length in line 534.
    Just for historical purposes:
    Commit 7380cf79 introduces a SEG_FAULT on large open-ended ranges:
    http://debbugs.gnu.org/7993.
    This bug was fixed in Commit 2e636af1which itself introduces a memory
    leak:
    https://lists.gnu.org/archive/html/bug-coreutils/2012-12/msg00017.html.
    This bug was fixed in Commit ec48bead which itself re-introduces the
    SEG_FAULT: reported here.

Nice one!
The attached should fix it.

thanks,
Pádraig.
>From fa62c3a2deb748f96ac67b731675d016700dc240 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]>
Date: Mon, 4 Feb 2013 11:39:20 +0000
Subject: [PATCH] cut: fix a segfault with disjoint open ended ranges
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* src/cut.c (set_fields): Don't access the bit array if
we've an open ended range that's outside any finite range.
* tests/misc/cut.pl: Add tests for this case.
Reported by Marcel Böhme in http://bugs.gnu.org/13627
---
 src/cut.c         |    3 ++-
 tests/misc/cut.pl |    2 ++
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/src/cut.c b/src/cut.c
index 36172c0..691c258 100644
--- a/src/cut.c
+++ b/src/cut.c
@@ -530,7 +530,8 @@ set_fields (const char *fieldstr)
   if (output_delimiter_specified
       && !complement
       && eol_range_start
-      && max_range_endpoint && !is_printable_field (eol_range_start))
+      && max_range_endpoint
+      && ((max_range_endpoint < eol_range_start) || !is_printable_field (eol_range_start)))
     mark_range_start (eol_range_start);
 
   free (rp);
diff --git a/tests/misc/cut.pl b/tests/misc/cut.pl
index 874c169..e925117 100755
--- a/tests/misc/cut.pl
+++ b/tests/misc/cut.pl
@@ -193,6 +193,8 @@ my @Tests =
   ['inval6', '-f', '-1,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
   # This would evoke a segfault from 5.3.0..8.10
   ['big-unbounded-b', '--output-d=:', '-b1234567890-', {IN=>''}, {OUT=>''}],
+  ['big-unbounded-b2a', '--output-d=:', '-b1,9-', {IN=>'123456789'}, {OUT=>"1:9\n"}],
+  ['big-unbounded-b2b', '--output-d=:', '-b1,1234567890-', {IN=>''}, {OUT=>''}],
   ['big-unbounded-c', '--output-d=:', '-c1234567890-', {IN=>''}, {OUT=>''}],
   ['big-unbounded-f', '--output-d=:', '-f1234567890-', {IN=>''}, {OUT=>''}],
 
-- 
1.7.6.4

Reply via email to