diff options
author | Pádraig Brady <P@draigBrady.com> | 2016-11-27 15:09:53 +0000 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2016-11-28 13:19:24 +0000 |
commit | a39641cbb8f37c5a19dd4820c6f6719c82d3e633 (patch) | |
tree | ee662cfc8add8265c1de488a9d281eba21c9d8a4 /src | |
parent | 6f30a99fa537adb029283cf2ef03cb4419350e6c (diff) | |
download | coreutils-a39641cbb8f37c5a19dd4820c6f6719c82d3e633.tar.xz |
tac: fix mem corruption when failing to read non seekable inputs
This was detected with ASAN, but can also be seen without ASAN with:
$ tac - - <&-
tac: standard input: read error: Bad file descriptor
*** Error in `tac': malloc(): memory corruption: 0x...
* src/tac.c (copy_to_temp): Don't close our output stream on
(possibly transient) output error, or on input error.
(temp_stream): clearerr() on the stream about to be reused,
to ensure future stream use is not impacted by transient errors.
* tests/misc/tac-2-nonseekable.sh: Add a test case.
* NEWS: Mention the bug fix.
Fixes http://bugs.gnu.org/25041
Diffstat (limited to 'src')
-rw-r--r-- | src/tac.c | 11 |
1 files changed, 4 insertions, 7 deletions
@@ -477,6 +477,7 @@ temp_stream (FILE **fp, char **file_name) } else { + clearerr (tmp_fp); if (fseeko (tmp_fp, 0, SEEK_SET) < 0 || ftruncate (fileno (tmp_fp), 0) < 0) { @@ -512,13 +513,13 @@ copy_to_temp (FILE **g_tmp, char **g_tempfile, int input_fd, char const *file) if (bytes_read == SAFE_READ_ERROR) { error (0, errno, _("%s: read error"), quotef (file)); - goto Fail; + return -1; } if (fwrite (G_buffer, 1, bytes_read, fp) != bytes_read) { error (0, errno, _("%s: write error"), quotef (file_name)); - goto Fail; + return -1; } /* Implicitly <= OFF_T_MAX due to preceding fwrite(), @@ -530,16 +531,12 @@ copy_to_temp (FILE **g_tmp, char **g_tempfile, int input_fd, char const *file) if (fflush (fp) != 0) { error (0, errno, _("%s: write error"), quotef (file_name)); - goto Fail; + return -1; } *g_tmp = fp; *g_tempfile = file_name; return bytes_copied; - - Fail: - fclose (fp); - return -1; } /* Copy INPUT_FD to a temporary, then tac that file. |