I noticed this issue when a --merge
sort was killed because of oom. It shouldn't.
Sort utility built from vanilla coreutils-8.4.tar.xz was not affected.
Sort utility built from coreutils-8.4-31.el6.src.rpm
fails and valgrind show that it was caused by coreutils-i18n.patch
The issue was caused by calls to mbsrtowcs
, wcsrtombs
which will modify *src
to NULL
causing later free()
to fail.
The code snippet
2371 month = (char *) xmalloc (len + 1);
2372
2373 tmp = (char *) xmalloc (len + 1);
2374 memcpy (tmp, s, len);
2375 tmp[len] = '\0';
2376 pp = (const char **)&tmp;
2377 month_wcs = (wchar_t *) xmalloc ((len + 1) * sizeof (wchar_t));
2378 memset (&state, '\0', sizeof(mbstate_t));
2379
2380 wclength = mbsrtowcs (month_wcs, pp, len + 1, &state);
2381 assert (wclength != (size_t)-1 && *pp == NULL);
2382
2383 for (i = 0; i < wclength; i++)
2384 {
2385 month_wcs[i] = towupper(month_wcs[i]);
2386 if (iswblank (month_wcs[i]))
2387 {
2388 month_wcs[i] = L'\0';
2389 break;
2390 }
2391 }
2392
2393 wpp = (const wchar_t **)&month_wcs;
2394
2395 mblength = wcsrtombs (month, wpp, len + 1, &state);
Valgrind report
==115765== 10,312 bytes in 7 blocks are definitely lost in loss record 18 of 23
==115765== at 0x4C29BE3: malloc (vg_replace_malloc.c:299)
==115765== by 0x40ED18: xmalloc (xmalloc.c:45)
==115765== by 0x4054EF: getmonth_mb (sort.c:2377)
==115765== by 0x407A19: keycompare_mb (sort.c:2651)
==115765== by 0x40626F: compare (sort.c:2793)
==115765== by 0x4080DA: mergefps (sort.c:2995)
==115765== by 0x408C83: merge (sort.c:3419)
==115765== by 0x403376: main (sort.c:4340)
==115765==
==115765== 12,374,304 bytes in 37,272 blocks are definitely lost in loss record 20 of 23
==115765== at 0x4C29BE3: malloc (vg_replace_malloc.c:299)
==115765== by 0x40ED18: xmalloc (xmalloc.c:45)
==115765== by 0x4054CB: getmonth_mb (sort.c:2373)
==115765== by 0x407A19: keycompare_mb (sort.c:2651)
==115765== by 0x40626F: compare (sort.c:2793)
==115765== by 0x408250: mergefps (sort.c:3093)
==115765== by 0x408C83: merge (sort.c:3419)
==115765== by 0x403376: main (sort.c:4340)
==115765==
==115765== 14,458,553 bytes in 37,273 blocks are definitely lost in loss record 21 of 23
==115765== at 0x4C29BE3: malloc (vg_replace_malloc.c:299)
==115765== by 0x40ED18: xmalloc (xmalloc.c:45)
==115765== by 0x4054CB: getmonth_mb (sort.c:2373)
==115765== by 0x407A0B: keycompare_mb (sort.c:2651)
==115765== by 0x40626F: compare (sort.c:2793)
==115765== by 0x408250: mergefps (sort.c:3093)
==115765== by 0x408C83: merge (sort.c:3419)
==115765== by 0x403376: main (sort.c:4340)
==115765==
==115765== 49,497,216 bytes in 37,272 blocks are definitely lost in loss record 22 of 23
==115765== at 0x4C29BE3: malloc (vg_replace_malloc.c:299)
==115765== by 0x40ED18: xmalloc (xmalloc.c:45)
==115765== by 0x4054EF: getmonth_mb (sort.c:2377)
==115765== by 0x407A19: keycompare_mb (sort.c:2651)
==115765== by 0x40626F: compare (sort.c:2793)
==115765== by 0x408250: mergefps (sort.c:3093)
==115765== by 0x408C83: merge (sort.c:3419)
==115765== by 0x403376: main (sort.c:4340)
==115765==
==115765== 57,831,180 bytes in 37,271 blocks are definitely lost in loss record 23 of 23
==115765== at 0x4C29BE3: malloc (vg_replace_malloc.c:299)
==115765== by 0x40ED18: xmalloc (xmalloc.c:45)
==115765== by 0x4054EF: getmonth_mb (sort.c:2377)
==115765== by 0x407A0B: keycompare_mb (sort.c:2651)
==115765== by 0x40626F: compare (sort.c:2793)
==115765== by 0x408250: mergefps (sort.c:3093)
==115765== by 0x408C83: merge (sort.c:3419)
==115765== by 0x403376: main (sort.c:4340)
==115765==
==115765== LEAK SUMMARY:
==115765== definitely lost: 134,186,793 bytes in 149,116 blocks
==115765== indirectly lost: 0 bytes in 0 blocks
==115765== possibly lost: 4,692 bytes in 4 blocks
==115765== still reachable: 2,103,088 bytes in 37 blocks
==115765== suppressed: 0 bytes in 0 blocks
==115765== Reachable blocks (those to which a pointer was found) are not shown.
==115765== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==115765==
==115765== For counts of detected and suppressed errors, rerun with: -v
==115765== ERROR SUMMARY: 11 errors from 11 contexts (suppressed: 0 from 0)