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