Brad Bishop | c68388fc | 2019-08-26 01:33:31 -0400 | [diff] [blame] | 1 | From 7f770b9c20da1a192dad8cb572a6391f2773285a Mon Sep 17 00:00:00 2001 |
| 2 | From: Jean Delvare <jdelvare@suse.de> |
| 3 | Date: Thu, 3 May 2018 14:31:55 +0200 |
| 4 | Subject: [PATCH 1/2] Don't leak temporary file on failed ed-style patch |
| 5 | |
| 6 | Now that we write ed-style patches to a temporary file before we |
| 7 | apply them, we need to ensure that the temporary file is removed |
| 8 | before we leave, even on fatal error. |
| 9 | |
| 10 | * src/pch.c (do_ed_script): Use global TMPEDNAME instead of local |
| 11 | tmpname. Don't unlink the file directly, instead tag it for removal |
| 12 | at exit time. |
| 13 | * src/patch.c (cleanup): Unlink TMPEDNAME at exit. |
| 14 | |
| 15 | This closes bug #53820: |
| 16 | https://savannah.gnu.org/bugs/index.php?53820 |
| 17 | |
| 18 | Fixes: 123eaff0d5d1 ("Fix arbitrary command execution in ed-style patches (CVE-2018-1000156)") |
| 19 | |
| 20 | Upstream-Status: Backport [http://git.savannah.gnu.org/cgit/patch.git/commit/?id=19599883ffb6a450d2884f081f8ecf68edbed7ee] |
| 21 | Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> |
| 22 | --- |
| 23 | src/common.h | 2 ++ |
| 24 | src/pch.c | 12 +++++------- |
| 25 | 2 files changed, 7 insertions(+), 7 deletions(-) |
| 26 | |
| 27 | diff --git a/src/common.h b/src/common.h |
| 28 | index ec50b40..22238b5 100644 |
| 29 | --- a/src/common.h |
| 30 | +++ b/src/common.h |
| 31 | @@ -94,10 +94,12 @@ XTERN char const *origsuff; |
| 32 | XTERN char const * TMPINNAME; |
| 33 | XTERN char const * TMPOUTNAME; |
| 34 | XTERN char const * TMPPATNAME; |
| 35 | +XTERN char const * TMPEDNAME; |
| 36 | |
| 37 | XTERN bool TMPINNAME_needs_removal; |
| 38 | XTERN bool TMPOUTNAME_needs_removal; |
| 39 | XTERN bool TMPPATNAME_needs_removal; |
| 40 | +XTERN bool TMPEDNAME_needs_removal; |
| 41 | |
| 42 | #ifdef DEBUGGING |
| 43 | XTERN int debug; |
| 44 | diff --git a/src/pch.c b/src/pch.c |
| 45 | index 16e001a..c1a62cf 100644 |
| 46 | --- a/src/pch.c |
| 47 | +++ b/src/pch.c |
| 48 | @@ -2392,7 +2392,6 @@ do_ed_script (char const *inname, char const *outname, |
| 49 | file_offset beginning_of_this_line; |
| 50 | size_t chars_read; |
| 51 | FILE *tmpfp = 0; |
| 52 | - char const *tmpname; |
| 53 | int tmpfd; |
| 54 | pid_t pid; |
| 55 | |
| 56 | @@ -2404,12 +2403,13 @@ do_ed_script (char const *inname, char const *outname, |
| 57 | invalid commands and treats the next line as a new command, which |
| 58 | can lead to arbitrary command execution. */ |
| 59 | |
| 60 | - tmpfd = make_tempfile (&tmpname, 'e', NULL, O_RDWR | O_BINARY, 0); |
| 61 | + tmpfd = make_tempfile (&TMPEDNAME, 'e', NULL, O_RDWR | O_BINARY, 0); |
| 62 | if (tmpfd == -1) |
| 63 | - pfatal ("Can't create temporary file %s", quotearg (tmpname)); |
| 64 | + pfatal ("Can't create temporary file %s", quotearg (TMPEDNAME)); |
| 65 | + TMPEDNAME_needs_removal = true; |
| 66 | tmpfp = fdopen (tmpfd, "w+b"); |
| 67 | if (! tmpfp) |
| 68 | - pfatal ("Can't open stream for file %s", quotearg (tmpname)); |
| 69 | + pfatal ("Can't open stream for file %s", quotearg (TMPEDNAME)); |
| 70 | } |
| 71 | |
| 72 | for (;;) { |
| 73 | @@ -2449,8 +2449,7 @@ do_ed_script (char const *inname, char const *outname, |
| 74 | write_fatal (); |
| 75 | |
| 76 | if (lseek (tmpfd, 0, SEEK_SET) == -1) |
| 77 | - pfatal ("Can't rewind to the beginning of file %s", quotearg (tmpname)); |
| 78 | - |
| 79 | + pfatal ("Can't rewind to the beginning of file %s", quotearg (TMPEDNAME)); |
| 80 | if (! dry_run && ! skip_rest_of_patch) { |
| 81 | int exclusive = *outname_needs_removal ? 0 : O_EXCL; |
| 82 | *outname_needs_removal = true; |
| 83 | @@ -2482,7 +2481,6 @@ do_ed_script (char const *inname, char const *outname, |
| 84 | } |
| 85 | |
| 86 | fclose (tmpfp); |
| 87 | - safe_unlink (tmpname); |
| 88 | |
| 89 | if (ofp) |
| 90 | { |
| 91 | -- |
| 92 | 2.17.0 |
| 93 | |