summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2015-08-05 22:04:54 +0000
committerdelphij <delphij@FreeBSD.org>2015-08-05 22:04:54 +0000
commit90e38dfd93e2eab866d5b6238f87a0ea4965b59a (patch)
treee02ca29c6fa37b9abbd5a409a9a376cd3cc11eab /usr.bin
parent8b20bb9f269c1f56f8edbac3189e5186f5c692cc (diff)
downloadFreeBSD-src-90e38dfd93e2eab866d5b6238f87a0ea4965b59a.zip
FreeBSD-src-90e38dfd93e2eab866d5b6238f87a0ea4965b59a.tar.gz
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]
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/patch/pathnames.h2
-rw-r--r--usr.bin/patch/pch.c18
2 files changed, 16 insertions, 4 deletions
diff --git a/usr.bin/patch/pathnames.h b/usr.bin/patch/pathnames.h
index d31300e..79d8fae 100644
--- a/usr.bin/patch/pathnames.h
+++ b/usr.bin/patch/pathnames.h
@@ -9,4 +9,4 @@
#include <paths.h>
-#define _PATH_ED "/bin/ed"
+#define _PATH_RED "/bin/red"
diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c
index e731ca1..5fadf62 100644
--- a/usr.bin/patch/pch.c
+++ b/usr.bin/patch/pch.c
@@ -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)
OpenPOWER on IntegriCloud