svn commit: r286346 - head/usr.bin/patch

Xin LI delphij at FreeBSD.org
Wed Aug 5 22:04:55 UTC 2015


Author: delphij
Date: Wed Aug  5 22:04:54 2015
New Revision: 286346
URL: https://svnweb.freebsd.org/changeset/base/286346

Log:
  Fix shell injection vulnerability in patch(1) via ed(1) by
  tightening sanity check of the input. [1]
  
  While I'm there also replace ed(1) with red(1) because we do
  not need the unrestricted functionality. [2]
  
  Obtained from:	Bitrig [1], DragonFly [2]
  Security:	CVE-2015-1418 [1]

Modified:
  head/usr.bin/patch/pathnames.h
  head/usr.bin/patch/pch.c

Modified: head/usr.bin/patch/pathnames.h
==============================================================================
--- head/usr.bin/patch/pathnames.h	Wed Aug  5 21:58:32 2015	(r286345)
+++ head/usr.bin/patch/pathnames.h	Wed Aug  5 22:04:54 2015	(r286346)
@@ -9,4 +9,4 @@
 
 #include <paths.h>
 
-#define	_PATH_ED		"/bin/ed"
+#define	_PATH_RED		"/bin/red"

Modified: head/usr.bin/patch/pch.c
==============================================================================
--- head/usr.bin/patch/pch.c	Wed Aug  5 21:58:32 2015	(r286345)
+++ head/usr.bin/patch/pch.c	Wed Aug  5 22:04:54 2015	(r286346)
@@ -1,4 +1,3 @@
-
 /*-
  * Copyright 1986, Larry Wall
  * 
@@ -1410,13 +1409,14 @@ do_ed_script(void)
 	char	*t;
 	off_t	beginning_of_this_line;
 	FILE	*pipefp = NULL;
+	int	continuation;
 
 	if (!skip_rest_of_patch) {
 		if (copy_file(filearg[0], TMPOUTNAME) < 0) {
 			unlink(TMPOUTNAME);
 			fatal("can't create temp file %s", TMPOUTNAME);
 		}
-		snprintf(buf, buf_size, "%s%s%s", _PATH_ED,
+		snprintf(buf, buf_size, "%s%s%s", _PATH_RED,
 		    verbose ? " " : " -s ", TMPOUTNAME);
 		pipefp = popen(buf, "w");
 	}
@@ -1434,7 +1434,19 @@ do_ed_script(void)
 		    (*t == 'a' || *t == 'c' || *t == 'd' || *t == 'i' || *t == 's')) {
 			if (pipefp != NULL)
 				fputs(buf, pipefp);
-			if (*t != 'd') {
+			if (*t == 's') {
+				for (;;) {
+					continuation = 0;
+					t = strchr(buf, '\0') - 1;
+					while (--t >= buf && *t == '\\')
+						continuation = !continuation;
+					if (!continuation ||
+					    pgets(true) == 0)
+						break;
+					if (pipefp != NULL)
+						fputs(buf, pipefp);
+				}
+			} else if (*t != 'd') {
 				while (pgets(true)) {
 					p_input_line++;
 					if (pipefp != NULL)


More information about the svn-src-head mailing list