Hi,

patch accepts arbitrary ed commands after encountering "s".  The "s"
ed command does not expect any further input, which makes it a one line
command like "d".  Yet, patch sends any lines until "." unchecked to ed
through its pipe, allowing command execution.

Example:

$ ls
ed.diff
$ cat ed.diff
0a
some text.
.
1s/.//
!/usr/bin/touch file.txt
$ touch a
$ patch a < ed.diff
Hmm...  Looks like an ed script to me...
0
!
10
done
$ ls
a       a.orig  ed.diff file.txt
$ _


Tobias

Index: pch.c
===================================================================
RCS file: /cvs/src/usr.bin/patch/pch.c,v
retrieving revision 1.49
diff -u -p -u -p -r1.49 pch.c
--- pch.c       13 Dec 2014 10:31:07 -0000      1.49
+++ pch.c       13 Dec 2014 15:25:51 -0000
@@ -1398,10 +1398,10 @@ do_ed_script(void)
                        ;
                /* POSIX defines allowed commands as {a,c,d,i,s} */
                if (isdigit((unsigned char)*buf) &&
-                   (*t == 'a' || *t == 'c' || *t == 'd' || *t == 'i' || *t == 
's')) {
+                   strchr("acdis", *t) != NULL) {
                        if (pipefp != NULL)
                                fputs(buf, pipefp);
-                       if (*t != 'd') {
+                       if (*t != 'd' && *t != 's') {
                                while (pgets(buf, sizeof buf, pfp) != NULL) {
                                        p_input_line++;
                                        if (pipefp != NULL)

Reply via email to