summaryrefslogtreecommitdiff
path: root/src/tac.c
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2010-08-28 17:45:29 +0200
committerJim Meyering <meyering@redhat.com>2010-08-28 19:28:20 +0200
commit777024889c0043004962834f4d9353cfa6847dd6 (patch)
treeab597978663b93ef1134cdcaa57ab921dd1d21f0 /src/tac.c
parentc984948ff5db81b760a8a1d9d5d9512754fc30c2 (diff)
downloadcoreutils-777024889c0043004962834f4d9353cfa6847dd6.tar.xz
tac: avoid double free
* src/tac.c (main): Reading a line longer than 16KiB would cause tac to realloc its primary buffer. Then, just before exit, tac would mistakenly free the original (now free'd) buffer. This bug was introduced by commit be6c13e7, "maint: always free a buffer, to avoid even semblance of a leak". * NEWS (Bug fixes): Mention it. * tests/misc/tac (double-free): New test, to exercise this. Reported by Salvo Tomaselli in <http://bugs.debian.org/594666>.
Diffstat (limited to 'src/tac.c')
-rw-r--r--src/tac.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/tac.c b/src/tac.c
index cec973601..859e0067a 100644
--- a/src/tac.c
+++ b/src/tac.c
@@ -633,7 +633,6 @@ main (int argc, char **argv)
if (! (read_size < half_buffer_size && half_buffer_size < G_buffer_size))
xalloc_die ();
G_buffer = xmalloc (G_buffer_size);
- void *buf = G_buffer;
if (sentinel_length)
{
strcpy (G_buffer, separator);
@@ -666,6 +665,9 @@ main (int argc, char **argv)
error (0, errno, "-");
ok = false;
}
- free (buf);
+
+ size_t offset = sentinel_length ? sentinel_length : 1;
+ free (G_buffer - offset);
+
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
}