On 30 January 2018 at 02:58, Kamil Dudka kdudka@redhat.com wrote:
On Wednesday, January 24, 2018 1:18:35 PM CET Yousong Zhou wrote:
This can be triggered by using month sort
The issue with the original code is that after the call to mbsrtowcs() and wcsrtombs() returns, the source pointer will be set to NULL causing the later free() call has no effect at all
The issue also exists in c6 branch
Thank you for sharing the patch! This was tracked as Fedora bug #1259942:
https://bugzilla.redhat.com/1259942
The bug was fixed in coreutils-8.23-11.fc22 and it is going to be fixed in the next major version of RHEL (and CentOS).
Kamil
Hi Kamil. I thought there must exist some kind of mechanism for backporting bugfixes of this kind into currently maintained versions. It should! It's an old bug already known and fixed in 2015 and still people are wasting time and getting frustrated by it in 2018!
yousong
SOURCES/coreutils-i18n.patch | 45 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 23 deletions(-)
diff --git a/SOURCES/coreutils-i18n.patch b/SOURCES/coreutils-i18n.patch index a3c7b33..cdcaffd 100644 --- a/SOURCES/coreutils-i18n.patch +++ b/SOURCES/coreutils-i18n.patch @@ -2963,7 +2963,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c line->keybeg = line_start; } } -@@ -1945,7 +2291,7 @@ human_numcompare (char const *a, char co +@@ -1943,7 +2289,7 @@ human_numcompare (char *a, char *b) hideously fast. */
static int @@ -2972,7 +2972,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1955,6 +2301,25 @@ numcompare (char const *a, char const *b +@@ -1953,6 +2299,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); }
@@ -2998,7 +2998,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c /* Work around a problem whereby the long double value returned by glibc's strtold ("NaN", ...) contains uninitialized bits: clear all bytes of A and B before calling strtold. FIXME: remove this function once -@@ -2005,7 +2370,7 @@ general_numcompare (char const *sa, char +@@ -2003,7 +2368,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */
static int @@ -3007,7 +3007,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, stru +@@ -2278,15 +2643,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0';
@@ -3025,7 +3025,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gke +@@ -2430,7 +2794,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3034,7 +3034,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar)))
-@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gke +@@ -2488,11 +2852,86 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option '-r' only applies to last-resort comparison")); }
@@ -3047,8 +3047,8 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c + register int lo = 0, hi = MONTHS_PER_YEAR, result;
- char *tmp;
- size_t wclength, mblength;
-+ const char **pp; -+ const wchar_t **wpp; ++ const char *pp; ++ const wchar_t *wpp;
- wchar_t *month_wcs;
- mbstate_t state;
@@ -3066,12 +3066,12 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c + tmp = (char *) xmalloc (len + 1);
- memcpy (tmp, s, len);
- tmp[len] = '\0';
-+ pp = (const char **)&tmp;
- month_wcs = (wchar_t *) xmalloc ((len + 1) * sizeof (wchar_t));
- memset (&state, '\0', sizeof(mbstate_t));
-+ wclength = mbsrtowcs (month_wcs, pp, len + 1, &state); -+ if (wclength == (size_t)-1 || *pp != NULL) ++ pp = tmp; ++ wclength = mbsrtowcs (month_wcs, &pp, len + 1, &state); ++ if (wclength == (size_t)-1 || pp != NULL)
- error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s));
- for (i = 0; i < wclength; i++)
@@ -3084,10 +3084,9 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c + }
- }
-+ wpp = (const wchar_t **)&month_wcs; -+ -+ mblength = wcsrtombs (month, wpp, len + 1, &state); -+ assert (mblength != (-1) && *wpp == NULL); ++ wpp = month_wcs; ++ mblength = wcsrtombs (month, &wpp, len + 1, &state); ++ assert (mblength != (-1) && wpp == NULL);
- do
- {
@@ -3123,7 +3122,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { struct keyfield *key = keylist;
-@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct +@@ -2577,7 +3016,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3132,7 +3131,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2695,6 +3135,209 @@ keycompare (struct line const *a, struct +@@ -2693,6 +3132,209 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; }
@@ -3342,7 +3341,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */
-@@ -2722,7 +3365,7 @@ compare (struct line const *a, struct li +@@ -2720,7 +3362,7 @@ compare (struct line const *a, struct li diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3351,7 +3350,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { /* Note xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4113,6 +4756,7 @@ set_ordering (char const *s, struct keyf +@@ -4111,6 +4753,7 @@ set_ordering (char const *s, struct keyf break; case 'f': key->translate = fold_toupper; @@ -3359,7 +3358,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c break; case 'g': key->general_numeric = true; -@@ -4190,7 +4834,7 @@ main (int argc, char **argv) +@@ -4188,7 +4831,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE);
hard_LC_COLLATE = hard_locale (LC_COLLATE);
@@ -3368,7 +3367,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif
-@@ -4211,6 +4855,29 @@ main (int argc, char **argv) +@@ -4209,6 +4852,29 @@ main (int argc, char **argv) thousands_sep = -1; }
@@ -3398,7 +3397,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c have_read_stdin = false; inittables ();
-@@ -4485,13 +5152,34 @@ main (int argc, char **argv) +@@ -4483,13 +5149,34 @@ main (int argc, char **argv)
case 't': {
@@ -3437,7 +3436,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4502,9 +5190,12 @@ main (int argc, char **argv) +@@ -4500,9 +5187,12 @@ main (int argc, char **argv) quote (optarg)); } }