Browse code

patch : Apply patch for CVE-2018-1000156

Change-Id: Iff162173bbd797f9d5f32fbc4b162630f0141d51
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/5178
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Sharath George

Xiaolin Li authored on 2018/05/22 07:13:05
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,197 @@
0
+From 123eaff0d5d1aebe128295959435b9ca5909c26d Mon Sep 17 00:00:00 2001
1
+From: Andreas Gruenbacher <agruen@gnu.org>
2
+Date: Fri, 6 Apr 2018 12:14:49 +0200
3
+Subject: Fix arbitrary command execution in ed-style patches
4
+ (CVE-2018-1000156)
5
+
6
+* src/pch.c (do_ed_script): Write ed script to a temporary file instead
7
+of piping it to ed: this will cause ed to abort on invalid commands
8
+instead of rejecting them and carrying on.
9
+* tests/ed-style: New test case.
10
+* tests/Makefile.am (TESTS): Add test case.
11
+---
12
+ src/pch.c         | 91 ++++++++++++++++++++++++++++++++++++++++---------------
13
+ tests/Makefile.am |  1 +
14
+ tests/ed-style    | 41 +++++++++++++++++++++++++
15
+ 3 files changed, 108 insertions(+), 25 deletions(-)
16
+ create mode 100644 tests/ed-style
17
+
18
+diff --git a/src/pch.c b/src/pch.c
19
+index 0c5cc26..4fd5a05 100644
20
+--- a/src/pch.c
21
+@@ -33,6 +33,7 @@
22
+ # include <io.h>
23
+ #endif
24
+ #include <safe.h>
25
++#include <sys/wait.h>
26
+ 
27
+ #define INITHUNKMAX 125			/* initial dynamic allocation size */
28
+ 
29
+@@ -2387,22 +2387,28 @@ do_ed_script (char const *inname, char const *outname,
30
+     static char const editor_program[] = EDITOR_PROGRAM;
31
+ 
32
+     file_offset beginning_of_this_line;
33
+-    FILE *pipefp = 0;
34
+     size_t chars_read;
35
++    FILE *tmpfp = 0;
36
++    char const *tmpname;
37
++    int tmpfd;
38
++    pid_t pid;
39
+ 
40
+-    if (! dry_run && ! skip_rest_of_patch) {
41
+-	int exclusive = *outname_needs_removal ? 0 : O_EXCL;
42
+-	assert (! inerrno);
43
+-	*outname_needs_removal = true;
44
+-	copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
45
+-	sprintf (buf, "%s %s%s", editor_program,
46
+-		 verbosity == VERBOSE ? "" : "- ",
47
+-		 outname);
48
+-	fflush (stdout);
49
+-	pipefp = popen(buf, binary_transput ? "wb" : "w");
50
+-	if (!pipefp)
51
+-	  pfatal ("Can't open pipe to %s", quotearg (buf));
52
+-    }
53
++    if (! dry_run && ! skip_rest_of_patch)
54
++      {
55
++	/* Write ed script to a temporary file.  This causes ed to abort on
56
++
57
++	tmpfd = make_tempfile (&tmpname, 'e', NULL, O_RDWR | O_BINARY, 0);
58
++	if (tmpfd == -1)
59
++	  pfatal ("Can't create temporary file %s", quotearg (tmpname));
60
++	tmpfp = fdopen (tmpfd, "w+b");
61
++	if (! tmpfp)
62
++	  pfatal ("Can't open stream for file %s", quotearg (tmpname));
63
++      }
64
++ 
65
+     for (;;) {
66
+ 	char ed_command_letter;
67
+ 	beginning_of_this_line = file_tell (pfp);
68
+@@ -2417,14 +2422,14 @@ do_ed_script (char const *inname, char const *outname,
69
+ 	}
70
+ 	ed_command_letter = get_ed_command_letter (buf);
71
+ 	if (ed_command_letter) {
72
+-	    if (pipefp)
73
+-		if (! fwrite (buf, sizeof *buf, chars_read, pipefp))
74
++	    if (tmpfp)
75
++		if (! fwrite (buf, sizeof *buf, chars_read, tmpfp))
76
+ 		    write_fatal ();
77
+ 	    if (ed_command_letter != 'd' && ed_command_letter != 's') {
78
+ 	        p_pass_comments_through = true;
79
+ 		while ((chars_read = get_line ()) != 0) {
80
+-		    if (pipefp)
81
+-			if (! fwrite (buf, sizeof *buf, chars_read, pipefp))
82
++		    if (tmpfp)
83
++			if (! fwrite (buf, sizeof *buf, chars_read, tmpfp))
84
+ 			    write_fatal ();
85
+ 		    if (chars_read == 2  &&  strEQ (buf, ".\n"))
86
+ 			break;
87
+@@ -2437,13 +2442,49 @@ do_ed_script (char const *inname, char const *outname,
88
+ 	    break;
89
+ 	}
90
+     }
91
+-    if (!pipefp)
92
++    if (!tmpfp)
93
+       return;
94
+-    if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, pipefp) == 0
95
+-	|| fflush (pipefp) != 0)
96
++    if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, tmpfp) == 0
97
++	|| fflush (tmpfp) != 0)
98
+       write_fatal ();
99
+-    if (pclose (pipefp) != 0)
100
+-      fatal ("%s FAILED", editor_program);
101
++
102
++    if (lseek (tmpfd, 0, SEEK_SET) == -1)
103
++      pfatal ("Can't rewind to the beginning of file %s", quotearg (tmpname));
104
++
105
++    if (! dry_run && ! skip_rest_of_patch) {
106
++	int exclusive = *outname_needs_removal ? 0 : O_EXCL;
107
++	*outname_needs_removal = true;
108
++	if (inerrno != ENOENT)
109
++	  {
110
++	    *outname_needs_removal = true;
111
++	    copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
112
++	  }
113
++	sprintf (buf, "%s %s%s", editor_program,
114
++		 verbosity == VERBOSE ? "" : "- ",
115
++		 outname);
116
++	fflush (stdout);
117
++
118
++	pid = fork();
119
++	if (pid == -1)
120
++	  pfatal ("Can't fork");
121
++	else if (pid == 0)
122
++	  {
123
++	    dup2 (tmpfd, 0);
124
++	    execl ("/bin/sh", "sh", "-c", buf, (char *) 0);
125
++	    _exit (2);
126
++	  }
127
++	else
128
++	  {
129
++	    int wstatus;
130
++	    if (waitpid (pid, &wstatus, 0) == -1
131
++	        || ! WIFEXITED (wstatus)
132
++		|| WEXITSTATUS (wstatus) != 0)
133
++	      fatal ("%s FAILED", editor_program);
134
++	  }
135
++    }
136
++
137
++    fclose (tmpfp);
138
++    safe_unlink (tmpname);
139
+ 
140
+     if (ofp)
141
+       {
142
+diff --git a/tests/ed-style b/tests/ed-style
143
+new file mode 100644
144
+index 0000000..d8c0689
145
+--- /dev/null
146
+@@ -0,0 +1,41 @@
147
++# Copyright (C) 2018 Free Software Foundation, Inc.
148
++#
149
++# Copying and distribution of this file, with or without modification,
150
++# in any medium, are permitted without royalty provided the copyright
151
++# notice and this notice are preserved.
152
++
153
++. $srcdir/test-lib.sh
154
++
155
++require cat
156
++use_local_patch
157
++use_tmpdir
158
++
159
++# ==============================================================
160
++
161
++cat > ed1.diff <<EOF
162
++0a
163
++foo
164
++.
165
++EOF
166
++
167
++check 'patch -e foo -i ed1.diff' <<EOF
168
++EOF
169
++
170
++check 'cat foo' <<EOF
171
++foo
172
++EOF
173
++
174
++cat > ed2.diff <<EOF
175
++1337a
176
++r !echo bar
177
++,p
178
++EOF
179
++
180
++check 'patch -e foo -i ed2.diff 2> /dev/null || echo "Status: $?"' <<EOF
181
++?
182
++Status: 2
183
++EOF
184
++
185
++check 'cat foo' <<EOF
186
++foo
187
++EOF
188
+-- 
189
+cgit v1.0-41-gc330
190
+
... ...
@@ -1,12 +1,13 @@
1 1
 Summary:        Program for modifying or creating files
2 2
 Name:           patch
3 3
 Version:        2.7.5
4
-Release:        3%{?dist}
4
+Release:        4%{?dist}
5 5
 License:        GPLv3+
6 6
 URL:            http://www.gnu.org/software/%{name}
7 7
 Source0:        ftp://ftp.gnu.org/gnu/patch/%{name}-%{version}.tar.gz
8
-%define sha1 patch=04d23f6e48e95efb07d12ccf44d1f35fb210f457
8
+%define sha1    patch=04d23f6e48e95efb07d12ccf44d1f35fb210f457
9 9
 Patch0:         patch-CVE-2018-6951.patch
10
+Patch1:         patch-CVE-2018-1000156.patch
10 11
 Group:          Development/Tools
11 12
 Vendor:         VMware, Inc.
12 13
 Distribution:   Photon
... ...
@@ -16,6 +17,8 @@ file typically created by the diff program.
16 16
 %prep
17 17
 %setup -q
18 18
 %patch0 -p1
19
+%patch1 -p1
20
+
19 21
 %build
20 22
 ./configure \
21 23
         --prefix=%{_prefix} \
... ...
@@ -30,6 +33,8 @@ make -k check |& tee %{_specdir}/%{name}-check-log || %{nocheck}
30 30
 %{_bindir}/*
31 31
 %{_mandir}/*/*
32 32
 %changelog
33
+*   Mon May 21 2018 Xiaolin Li <xiaolinl@vmware.com> 2.7.5-4
34
+-   Apply patch for CVE-2018-1000156
33 35
 *   Tue Apr 17 2018 Xiaolin Li <xiaolinl@vmware.com> 2.7.5-3
34 36
 -   Apply patch for CVE-2018-6951
35 37
 *   Tue May 24 2016 Priyesh Padmavilasom <ppadmavilasom@vmware.com> 2.7.5-2