Subject: bug#16855: closed (Re: bug#16855: report a bug about shuf)

From: [email-masked] (GNU bug Tracking System)
Date: Sun, 23 Feb 2014 23:38:03 +0000

Your bug report

#16855: report a bug about shuf

which was filed against the coreutils package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
16855: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16855
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#16855: report a bug about shuf
From: Paul Eggert <[email-masked]>
To: valiant xiao <[email-masked]>, [email-masked]
Cc: [email-masked], Yu Chen <[email-masked]>
Date: Sun, 23 Feb 2014 15:37:41 -0800
List-Id: <debbugs-submit.debbugs.gnu.org>

Thanks for the bug report.  I've committed the attached patch.
From 24eb395471176e24762b08bfcef7562911537504 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sun, 23 Feb 2014 15:34:48 -0800
Subject: [PATCH] shuf: with -r, don't dump core if the input is empty

Problem reported by valiant xiao in <http://bugs.gnu.org/16855>.
* NEWS: Document this.
* src/shuf.c (main): With -r, report an error if the input is empty.
* tests/misc/shuf.sh: Test for the bug.
---
 NEWS               |  3 +++
 src/shuf.c         | 15 +++++++++++----
 tests/misc/shuf.sh |  4 ++++
 3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/NEWS b/NEWS
index e72942b..2df246d 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   it would display an error, requiring --no-dereference to avoid the issue.
   [bug introduced in coreutils-5.3.0]
 
+  shuf -r no longer dumps core if the input is empty.
+  [bug introduced in coreutils-8.22]
+
 ** New features
 
   od accepts a new option: --endian=TYPE to handle inputs with different byte
diff --git a/src/shuf.c b/src/shuf.c
index d4641fe..2a91072 100644
--- a/src/shuf.c
+++ b/src/shuf.c
@@ -576,11 +576,18 @@ main (int argc, char **argv)
   /* Generate output according to requested method */
   if (repeat)
     {
-      if (input_range)
-        i = write_random_numbers (randint_source, head_lines,
-                                  lo_input, hi_input, eolbyte);
+      if (head_lines == 0)
+        i = 0;
       else
-        i = write_random_lines (randint_source, head_lines, line, n_lines);
+        {
+          if (n_lines == 0)
+            error (EXIT_FAILURE, 0, _("No lines to repeat"));
+          if (input_range)
+            i = write_random_numbers (randint_source, head_lines,
+                                      lo_input, hi_input, eolbyte);
+          else
+            i = write_random_lines (randint_source, head_lines, line, n_lines);
+        }
     }
   else
     {
diff --git a/tests/misc/shuf.sh b/tests/misc/shuf.sh
index d3ea1f2..d7251d1 100755
--- a/tests/misc/shuf.sh
+++ b/tests/misc/shuf.sh
@@ -43,6 +43,10 @@ compare in out1 || { fail=1; echo "not a permutation" 1>&2; }
 t=$(shuf -e a b c d e | sort | fmt)
 test "$t" = 'a b c d e' || { fail=1; echo "not a permutation" 1>&2; }
 
+# coreutils-8.22 dumps core.
+shuf -er
+test $? -eq 1 || fail=1
+
 # Before coreutils-6.3, this would infloop.
 # "seq 1860" produces 8193 (8K + 1) bytes of output.
 seq 1860 | shuf > /dev/null || fail=1
-- 
1.8.5.3

Subject: report a bug about shuf
From: valiant xiao <[email-masked]>
To: [email-masked]
Cc: [email-masked], Yu Chen <[email-masked]>, [email-masked]
Date: Sun, 23 Feb 2014 16:03:59 +0800
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi,

We have found a bug in shuf, and we think it may be result a security
problem.
we compile coreutils 8.22 which is download from
http://ftp.gnu.org/gnu/coreutils/, and run it on
my box that is ubuntu 12.04 x64. the bug details as follows.

### Bug overview

    shuf -er or shuf -eer [ segment fault]
    impact [coreutils 8.22 ]

```
[15:03:59]xqx@server:~/data/xqx/projects/coreutils-8.22$
./obj-gcov/src/shuf -er
Segmentation fault (core dumped)

```

### Analysis

    when shuf execute -e without give the expected input lines, it will
assign n_lines to 0 in "write_random_lines" while the "repeat" (-r) be set.
and this var will be as the genmax parameter when "randint_genmax" function
called. the code as follows in shuf.c:

```
369   for (i = 0; i < count; i++)
370     {
371       const randint j = randint_choose (s, n_lines);
372       char *const *p = lines + j;
373       size_t len = p[1] - p[0];
374       if (fwrite (p[0], sizeof *p[0], len, stdout) != len)
375         return -1;
376     }
377

```

    'j' will be a random number between 0-0xffffffffffffffff in my 64bit
ubuntu, and 'p' will be a unexpected point which will be access next. when
p point to an ilegal memory, it will be error when access it, which may be
result in a Segmentation fault.

    if an attacker could control the random which gened by randint_choose,
it may be get the infomation without an legal authority.  However, It may
be difficult.

yours

xqx