You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
3.4KB

  1. From 19599883ffb6a450d2884f081f8ecf68edbed7ee 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] Don't leak temporary file on failed ed-style patch
  5. Now that we write ed-style patches to a temporary file before we
  6. apply them, we need to ensure that the temporary file is removed
  7. before we leave, even on fatal error.
  8. * src/pch.c (do_ed_script): Use global TMPEDNAME instead of local
  9. tmpname. Don't unlink the file directly, instead tag it for removal
  10. at exit time.
  11. * src/patch.c (cleanup): Unlink TMPEDNAME at exit.
  12. This closes bug #53820:
  13. https://savannah.gnu.org/bugs/index.php?53820
  14. Fixes: 123eaff0d5d1 ("Fix arbitrary command execution in ed-style patches (CVE-2018-1000156)")
  15. ---
  16. src/common.h | 2 ++
  17. src/patch.c | 1 +
  18. src/pch.c | 11 +++++------
  19. 3 files changed, 8 insertions(+), 6 deletions(-)
  20. diff --git a/src/common.h b/src/common.h
  21. index 904a3f8..53c5e32 100644
  22. --- a/src/common.h
  23. +++ b/src/common.h
  24. @@ -94,10 +94,12 @@ XTERN char const *origsuff;
  25. XTERN char const * TMPINNAME;
  26. XTERN char const * TMPOUTNAME;
  27. XTERN char const * TMPPATNAME;
  28. +XTERN char const * TMPEDNAME;
  29. XTERN bool TMPINNAME_needs_removal;
  30. XTERN bool TMPOUTNAME_needs_removal;
  31. XTERN bool TMPPATNAME_needs_removal;
  32. +XTERN bool TMPEDNAME_needs_removal;
  33. #ifdef DEBUGGING
  34. XTERN int debug;
  35. diff --git a/src/patch.c b/src/patch.c
  36. index 3fcaec5..9146597 100644
  37. --- a/src/patch.c
  38. +++ b/src/patch.c
  39. @@ -1999,6 +1999,7 @@ cleanup (void)
  40. remove_if_needed (TMPINNAME, &TMPINNAME_needs_removal);
  41. remove_if_needed (TMPOUTNAME, &TMPOUTNAME_needs_removal);
  42. remove_if_needed (TMPPATNAME, &TMPPATNAME_needs_removal);
  43. + remove_if_needed (TMPEDNAME, &TMPEDNAME_needs_removal);
  44. remove_if_needed (TMPREJNAME, &TMPREJNAME_needs_removal);
  45. output_files (NULL);
  46. }
  47. diff --git a/src/pch.c b/src/pch.c
  48. index 79a3c99..1bb3153 100644
  49. --- a/src/pch.c
  50. +++ b/src/pch.c
  51. @@ -2396,7 +2396,6 @@ do_ed_script (char const *inname, char const *outname,
  52. file_offset beginning_of_this_line;
  53. size_t chars_read;
  54. FILE *tmpfp = 0;
  55. - char const *tmpname;
  56. int tmpfd;
  57. pid_t pid;
  58. @@ -2411,12 +2410,13 @@ do_ed_script (char const *inname, char const *outname,
  59. invalid commands and treats the next line as a new command, which
  60. can lead to arbitrary command execution. */
  61. - tmpfd = make_tempfile (&tmpname, 'e', NULL, O_RDWR | O_BINARY, 0);
  62. + tmpfd = make_tempfile (&TMPEDNAME, 'e', NULL, O_RDWR | O_BINARY, 0);
  63. if (tmpfd == -1)
  64. - pfatal ("Can't create temporary file %s", quotearg (tmpname));
  65. + pfatal ("Can't create temporary file %s", quotearg (TMPEDNAME));
  66. + TMPEDNAME_needs_removal = true;
  67. tmpfp = fdopen (tmpfd, "w+b");
  68. if (! tmpfp)
  69. - pfatal ("Can't open stream for file %s", quotearg (tmpname));
  70. + pfatal ("Can't open stream for file %s", quotearg (TMPEDNAME));
  71. }
  72. for (;;) {
  73. @@ -2457,7 +2457,7 @@ do_ed_script (char const *inname, char const *outname,
  74. write_fatal ();
  75. if (lseek (tmpfd, 0, SEEK_SET) == -1)
  76. - pfatal ("Can't rewind to the beginning of file %s", quotearg (tmpname));
  77. + pfatal ("Can't rewind to the beginning of file %s", quotearg (TMPEDNAME));
  78. if (inerrno != ENOENT)
  79. {
  80. @@ -2484,7 +2484,6 @@ do_ed_script (char const *inname, char const *outname,
  81. pfatal ("Failed to duplicate standard input");
  82. fclose (tmpfp);
  83. - safe_unlink (tmpname);
  84. if (ofp)
  85. {