Hello.
From responses to the 'beep' bug it was noticed that GNU patch files can
result in arbitrary code execution via 'ed'. [1]
<http://rachelbythebay.com/w/2018/04/05/bangpatch/>
Included is a patch that removes that dangerous feature.
From 3f47f3052dfdc79d4fd9dca8db27a7a80227fd40 Mon Sep 17 00:00:00 2001
From: Raymond Nicholson <ra...@airmail.cc>
Date: Thu, 5 Apr 2018 21:12:16 +0100
Subject: [PATCH] Remove the 'ed script' feature for security reasons. As it
allowed arbitrary code execution.
* src/pch.c: Deleted do_ed_script function.
* src/pch.h: Deleted do_ed_script prototype.
* src/patch.c: Replace the code to call do_ed_script with an fatal error.
---
src/patch.c | 13 +----------
src/pch.c | 77 -------------------------------------------------------------
src/pch.h | 1 -
3 files changed, 1 insertion(+), 90 deletions(-)
diff --git a/src/patch.c b/src/patch.c
index 0fe6d72..1805156 100644
--- a/src/patch.c
+++ b/src/patch.c
@@ -332,18 +332,7 @@ main (int argc, char **argv)
else
TMPOUTNAME_needs_removal = true;
if (diff_type == ED_DIFF) {
- outstate.zero_output = false;
- somefailed |= skip_rest_of_patch;
- do_ed_script (inname, TMPOUTNAME, &TMPOUTNAME_needs_removal,
- outstate.ofp);
- if (! dry_run && ! outfile && ! skip_rest_of_patch)
- {
- if (fstat (outfd, &tmpoutst) != 0)
- pfatal ("%s", TMPOUTNAME);
- outstate.zero_output = tmpoutst.st_size == 0;
- }
- close (outfd);
- outfd = -1;
+ pfatal ("ed diff scripts are no longer supported.", TMPOUTNAME);
} else {
int got_hunk;
bool apply_anyway = merge; /* don't try to reverse when merging */
diff --git a/src/pch.c b/src/pch.c
index bc6278c..e34a499 100644
--- a/src/pch.c
+++ b/src/pch.c
@@ -2380,83 +2380,6 @@ get_ed_command_letter (char const *line)
return 0;
}
-/* Apply an ed script by feeding ed itself. */
-
-void
-do_ed_script (char const *inname, char const *outname,
- bool *outname_needs_removal, FILE *ofp)
-{
- static char const editor_program[] = EDITOR_PROGRAM;
-
- file_offset beginning_of_this_line;
- FILE *pipefp = 0;
- size_t chars_read;
-
- if (! dry_run && ! skip_rest_of_patch) {
- int exclusive = *outname_needs_removal ? 0 : O_EXCL;
- assert (! inerrno);
- *outname_needs_removal = true;
- copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
- sprintf (buf, "%s %s%s", editor_program,
- verbosity == VERBOSE ? "" : "- ",
- outname);
- fflush (stdout);
- pipefp = popen(buf, binary_transput ? "wb" : "w");
- if (!pipefp)
- pfatal ("Can't open pipe to %s", quotearg (buf));
- }
- for (;;) {
- char ed_command_letter;
- beginning_of_this_line = file_tell (pfp);
- chars_read = get_line ();
- if (! chars_read) {
- next_intuit_at(beginning_of_this_line,p_input_line);
- break;
- }
- ed_command_letter = get_ed_command_letter (buf);
- if (ed_command_letter) {
- if (pipefp)
- if (! fwrite (buf, sizeof *buf, chars_read, pipefp))
- write_fatal ();
- if (ed_command_letter != 'd' && ed_command_letter != 's') {
- p_pass_comments_through = true;
- while ((chars_read = get_line ()) != 0) {
- if (pipefp)
- if (! fwrite (buf, sizeof *buf, chars_read, pipefp))
- write_fatal ();
- if (chars_read == 2 && strEQ (buf, ".\n"))
- break;
- }
- p_pass_comments_through = false;
- }
- }
- else {
- next_intuit_at(beginning_of_this_line,p_input_line);
- break;
- }
- }
- if (!pipefp)
- return;
- if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, pipefp) == 0
- || fflush (pipefp) != 0)
- write_fatal ();
- if (pclose (pipefp) != 0)
- fatal ("%s FAILED", editor_program);
-
- if (ofp)
- {
- FILE *ifp = fopen (outname, binary_transput ? "rb" : "r");
- int c;
- if (!ifp)
- pfatal ("can't open '%s'", outname);
- while ((c = getc (ifp)) != EOF)
- if (putc (c, ofp) == EOF)
- write_fatal ();
- if (ferror (ifp) || fclose (ifp) != 0)
- read_fatal ();
- }
-}
-
void
pch_normalize (enum diff format)
{
diff --git a/src/pch.h b/src/pch.h
index 9565ac4..68b50f1 100644
--- a/src/pch.h
+++ b/src/pch.h
@@ -43,7 +43,6 @@ size_t pch_line_len (lin) _GL_ATTRIBUTE_PURE;
const char *pch_name(enum nametype) _GL_ATTRIBUTE_PURE;
bool pch_copy (void) _GL_ATTRIBUTE_PURE;
bool pch_rename (void) _GL_ATTRIBUTE_PURE;
-void do_ed_script (char const *, char const *, bool *, FILE *);
void open_patch_file (char const *);
void re_patch (void);
void pch_normalize (enum diff);
--
2.16.3