File coreutils-i18n-no-alloca.patch of Package coreutils.1252

From: Bernhard Voelker <mail@bernhard-voelker.de>
Subject: sort, join, uniq: avoid segmentation fault with long input lines

    The i18n patches used to make use of the alloca function which cannot
    guarantee success, and the result can not be tested for success/failure.
    From `man alloca`:
      "If the allocation causes stack overflow, program behavior is undefined."
    Simply replace all uses of alloca by xmalloc.

    - Avoid segmentation fault in "join -i" with long line input
      (bnc#798541, VUL-1)
      
       Test case:
         $ perl -e 'print "1","A"x50000000,"\r\n\r\n"' > /tmp/test.txt
         $ join -i /tmp/test.txt /tmp/test.txt
       
       * src/join.c: Instead of usig unreliable alloca() stack allocation,
         use heap allocation via xmalloc()+free().
         (coreutils-i18n.patch, from Philipp Thomas <pth@suse.de>)

    - Avoid segmentation fault in "sort -d" and "sort -M" with long line input
      (bnc#798538, VUL-1)

      Test cases:
        $ perl -e 'print "1","A"x50000000,"\r\n\r\n"' | sort -d
        $ perl -e 'print "1","A"x50000000,"\r\n\r\n"' | sort -M        
      
      * src/sort.c: Instead of usig unreliable alloca() stack allocation,
        use heap allocation via xmalloc()+free().
        (coreutils-i18n.patch, from Philipp Thomas <pth@suse.de>)

    - Avoid segmentation fault in "uniq" with long line input
      (bnc#796243, VUL-1)

      Test case:
        $ perl -e 'print "1","\0"x50000000,"\r\n\r\n"' | uniq

      * src/cut.c: Instead of usig unreliable alloca() stack allocation,
        use heap allocation via xmalloc()+free().
        (coreutils-i18n.patch)

---
 src/join.c |   21 ++++++++++++++++++---
 src/sort.c |   13 +++++++++----
 src/uniq.c |   16 ++++++++++++----
 3 files changed, 39 insertions(+), 11 deletions(-)

Index: src/join.c
===================================================================
--- src/join.c.orig
+++ src/join.c
@@ -478,6 +478,7 @@ keycmp (struct line const *line1, struct
   size_t len[2]; 	/* Length of fields to compare.  */
   int diff;
   int i, j;
+  int mallocd = 0;
 
   if (jf_1 < line1->nfields)
     {
@@ -519,7 +520,8 @@ keycmp (struct line const *line1, struct
 
         for (i = 0; i < 2; i++)
           {
-            copy[i] = alloca (len[i] + 1);
+            mallocd = 1;
+            copy[i] = xmalloc (len[i] + 1);
 
             for (j = 0; j < MIN (len[0], len[1]);)
               {
@@ -559,7 +561,8 @@ keycmp (struct line const *line1, struct
       {
         for (i = 0; i < 2; i++)
           {
-            copy[i] = alloca (len[i] + 1);
+            mallocd = 1;
+            copy[i] = xmalloc (len[i] + 1);
 
             for (j = 0; j < MIN (len[0], len[1]); j++)
               copy[i][j] = toupper (beg[i][j]);
@@ -575,9 +578,21 @@ keycmp (struct line const *line1, struct
     }
 
   if (hard_LC_COLLATE)
-    return xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]);
+    {
+      diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]);
+
+      if (mallocd)
+        for (i = 0; i < 2; i++)
+          free (copy[i]);
+
+      return diff;
+    }
+
   diff = memcmp (copy[0], copy[1], MIN (len[0], len[1]));
 
+  if (mallocd)
+    for (i = 0; i < 2; i++)
+      free (copy[i]);
 
   if (diff)
     return diff;
Index: src/sort.c
===================================================================
--- src/sort.c.orig
+++ src/sort.c
@@ -2830,13 +2830,13 @@ getmonth_mb (const char *s, size_t len,
   if (len == 0)
     return 0;
 
-  month = (char *) alloca (len + 1);
+  month = (char *) xmalloc (len + 1);
 
-  tmp = (char *) alloca (len + 1);
+  tmp = (char *) xmalloc (len + 1);
   memcpy (tmp, s, len);
   tmp[len] = '\0';
   pp = (const char **)&tmp;
-  month_wcs = (wchar_t *) alloca ((len + 1) * sizeof (wchar_t));
+  month_wcs = (wchar_t *) xmalloc ((len + 1) * sizeof (wchar_t));
   memset (&state, '\0', sizeof(mbstate_t));
 
   wclength = mbsrtowcs (month_wcs, pp, len + 1, &state);
@@ -2875,6 +2875,10 @@ getmonth_mb (const char *s, size_t len,
   result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name))
       ? monthtab[lo].val : 0);
 
+  free (month);
+  free (tmp);
+  free (month_wcs);
+
   return result;
 }
 #endif
@@ -3136,7 +3140,7 @@ keycompare_mb (const struct line *a, con
         {
           if (ignore || translate)
             {
-              char *copy_a = (char *) alloca (lena + 1 + lenb + 1);
+              char *copy_a = xmalloc (lena + 1 + lenb + 1);
               char *copy_b = copy_a + lena + 1;
               size_t new_len_a, new_len_b;
               size_t i, j;
@@ -3212,6 +3216,7 @@ keycompare_mb (const struct line *a, con
               IGNORE_CHARS (new_len_b, lenb, textb, copy_b,
                             wc_b, mblength_b, state_b);
               diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b);
+              free(copy_a);
             }
           else if (lena == 0)
             diff = - NONZERO (lenb);
Index: src/uniq.c
===================================================================
--- src/uniq.c.orig
+++ src/uniq.c
@@ -349,14 +349,19 @@ different (char *old, char *new, size_t
     {
       size_t i;
 
-      copy_old = alloca (oldlen + 1);
-      copy_new = alloca (oldlen + 1);
+      copy_old = xmalloc (sizeof(char) * (oldlen + 1));
+      copy_new = xmalloc (sizeof(char) * (oldlen + 1));
 
       for (i = 0; i < oldlen; i++)
         {
           copy_old[i] = toupper (old[i]);
           copy_new[i] = toupper (new[i]);
         }
+
+      bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen);
+      free (copy_old);
+      free (copy_new);
+      return rc;
     }
   else
     {
@@ -389,7 +394,7 @@ different_multi (const char *old, const
 
   for (i = 0; i < 2; i++)
     {
-      copy[i] = alloca (len[i] + 1);
+      copy[i] = xmalloc (len[i] + 1);
 
       for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++)
         {
@@ -430,7 +435,10 @@ different_multi (const char *old, const
       len[i] = j;
     }
 
-  return xmemcoll (copy[0], len[0], copy[1], len[1]);
+  int rc = xmemcoll (copy[0], len[0], copy[1], len[1]);
+  free (copy[0]);
+  free (copy[1]);
+  return rc;
 }
 #endif
 
openSUSE Build Service is sponsored by