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

Reply via email to