diff --git a/ed-style-07-dont-leak-tmp-file.patch b/ed-style-07-dont-leak-tmp-file.patch new file mode 100644 index 0000000..ed8372c --- /dev/null +++ b/ed-style-07-dont-leak-tmp-file.patch @@ -0,0 +1,95 @@ +From: Jean Delvare +Date: Thu, 3 May 2018 14:31:55 +0200 +Subject: Don't leak temporary file on failed ed-style patch +Git-commit: 19599883ffb6a450d2884f081f8ecf68edbed7ee +Patch-mainline: yes +References: bsc#1092500, savannah#53820 + +Now that we write ed-style patches to a temporary file before we +apply them, we need to ensure that the temporary file is removed +before we leave, even on fatal error. + +* src/pch.c (do_ed_script): Use global TMPEDNAME instead of local + tmpname. Don't unlink the file directly, instead tag it for removal + at exit time. +* src/patch.c (cleanup): Unlink TMPEDNAME at exit. + +This closes bug #53820: +https://savannah.gnu.org/bugs/index.php?53820 + +Fixes: 123eaff0d5d1 ("Fix arbitrary command execution in ed-style patches (CVE-2018-1000156)") +--- + src/common.h | 2 ++ + src/patch.c | 1 + + src/pch.c | 11 +++++------ + 3 files changed, 8 insertions(+), 6 deletions(-) + +--- a/src/common.h ++++ b/src/common.h +@@ -94,10 +94,12 @@ XTERN char const *origsuff; + XTERN char const * TMPINNAME; + XTERN char const * TMPOUTNAME; + XTERN char const * TMPPATNAME; ++XTERN char const * TMPEDNAME; + + XTERN bool TMPINNAME_needs_removal; + XTERN bool TMPOUTNAME_needs_removal; + XTERN bool TMPPATNAME_needs_removal; ++XTERN bool TMPEDNAME_needs_removal; + + #ifdef DEBUGGING + XTERN int debug; +--- a/src/patch.c ++++ b/src/patch.c +@@ -1999,6 +1999,7 @@ cleanup (void) + remove_if_needed (TMPINNAME, &TMPINNAME_needs_removal); + remove_if_needed (TMPOUTNAME, &TMPOUTNAME_needs_removal); + remove_if_needed (TMPPATNAME, &TMPPATNAME_needs_removal); ++ remove_if_needed (TMPEDNAME, &TMPEDNAME_needs_removal); + remove_if_needed (TMPREJNAME, &TMPREJNAME_needs_removal); + output_files (NULL); + } +--- a/src/pch.c ++++ b/src/pch.c +@@ -2392,7 +2392,6 @@ do_ed_script (char const *inname, char c + file_offset beginning_of_this_line; + size_t chars_read; + FILE *tmpfp = 0; +- char const *tmpname; + int tmpfd; + pid_t pid; + int exclusive = *outname_needs_removal ? 0 : O_EXCL; +@@ -2406,12 +2405,13 @@ do_ed_script (char const *inname, char c + invalid commands and treats the next line as a new command, which + can lead to arbitrary command execution. */ + +- tmpfd = make_tempfile (&tmpname, 'e', NULL, O_RDWR | O_BINARY, 0); ++ tmpfd = make_tempfile (&TMPEDNAME, 'e', NULL, O_RDWR | O_BINARY, 0); + if (tmpfd == -1) +- pfatal ("Can't create temporary file %s", quotearg (tmpname)); ++ pfatal ("Can't create temporary file %s", quotearg (TMPEDNAME)); ++ TMPEDNAME_needs_removal = true; + tmpfp = fdopen (tmpfd, "w+b"); + if (! tmpfp) +- pfatal ("Can't open stream for file %s", quotearg (tmpname)); ++ pfatal ("Can't open stream for file %s", quotearg (TMPEDNAME)); + } + + for (;;) { +@@ -2451,7 +2451,7 @@ do_ed_script (char const *inname, char c + write_fatal (); + + if (lseek (tmpfd, 0, SEEK_SET) == -1) +- pfatal ("Can't rewind to the beginning of file %s", quotearg (tmpname)); ++ pfatal ("Can't rewind to the beginning of file %s", quotearg (TMPEDNAME)); + + if (inerrno != ENOENT) + { +@@ -2480,7 +2480,6 @@ do_ed_script (char const *inname, char c + } + + fclose (tmpfp); +- safe_unlink (tmpname); + + if (ofp) + { diff --git a/ed-style-08-dont-leak-tmp-file-multi.patch b/ed-style-08-dont-leak-tmp-file-multi.patch new file mode 100644 index 0000000..c990bbb --- /dev/null +++ b/ed-style-08-dont-leak-tmp-file-multi.patch @@ -0,0 +1,72 @@ +From: Jean Delvare +Date: Mon, 7 May 2018 15:14:45 +0200 +Subject: Don't leak temporary file on failed multi-file ed-style patch +Git-commit: 369dcccdfa6336e5a873d6d63705cfbe04c55727 +Patch-mainline: yes +References: bsc#1092500, savannah#53820 + +The previous fix worked fine with single-file ed-style patches, but +would still leak temporary files in the case of multi-file ed-style +patch. Fix that case as well, and extend the test case to check for +it. + +* src/patch.c (main): Unlink TMPEDNAME if needed before moving to + the next file in a patch. + +This closes bug #53820: +https://savannah.gnu.org/bugs/index.php?53820 + +Fixes: 123eaff0d5d1 ("Fix arbitrary command execution in ed-style patches (CVE-2018-1000156)") +Fixes: 19599883ffb6 ("Don't leak temporary file on failed ed-style patch") +--- + src/patch.c | 1 + + tests/ed-style | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 32 insertions(+) + +--- a/src/patch.c ++++ b/src/patch.c +@@ -236,6 +236,7 @@ main (int argc, char **argv) + } + remove_if_needed (TMPOUTNAME, &TMPOUTNAME_needs_removal); + } ++ remove_if_needed (TMPEDNAME, &TMPEDNAME_needs_removal); + + if (! skip_rest_of_patch && ! file_type) + { +--- a/tests/ed-style ++++ b/tests/ed-style +@@ -38,3 +38,34 @@ EOF + check 'cat foo' < ed3.diff < baz <