python/isort: update to 6.0.0
[oi-userland.git] / components / text / patch / patches / 02-CVE-2018-1000156_and_CVE-2018-20969_and_CVE-2019-13638.patch
blob431c0f216b95650d9611afc29a3c0f1b7d0f8704
1 From: Andreas Gruenbacher <agruen@gnu.org>
2 Date: Fri, 6 Apr 2018 11:34:51 +0200
3 Subject: Allow input files to be missing for ed-style patches
4 Patch-mainline: yes
5 Git-commit: b5a91a01e5d0897facdd0f49d64b76b0f02b43e1
6 References: bsc#1088420, savannah#53566, CVE-2018-1000156
8 * src/pch.c (do_ed_script): Allow input files to be missing so that new
9 files will be created as with non-ed-style patches.
10 ---
11 src/pch.c | 8 +++++---
12 1 file changed, 5 insertions(+), 3 deletions(-)
14 --- a/src/pch.c
15 +++ b/src/pch.c
16 @@ -2394,9 +2394,11 @@ do_ed_script (char const *inname, char c
18 if (! dry_run && ! skip_rest_of_patch) {
19 int exclusive = *outname_needs_removal ? 0 : O_EXCL;
20 - assert (! inerrno);
21 - *outname_needs_removal = true;
22 - copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
23 + if (inerrno != ENOENT)
24 + {
25 + *outname_needs_removal = true;
26 + copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
27 + }
28 sprintf (buf, "%s %s%s", editor_program,
29 verbosity == VERBOSE ? "" : "- ",
30 outname);
31 From: Andreas Gruenbacher <agruen@gnu.org>
32 Date: Fri, 6 Apr 2018 12:14:49 +0200
33 Subject: Fix arbitrary command execution in ed-style patches
34 Patch-mainline: yes
35 Git-commit: 123eaff0d5d1aebe128295959435b9ca5909c26d
36 References: bsc#1088420, savannah#53566, CVE-2018-1000156
38 * src/pch.c (do_ed_script): Write ed script to a temporary file instead
39 of piping it to ed: this will cause ed to abort on invalid commands
40 instead of rejecting them and carrying on.
41 * tests/ed-style: New test case.
42 * tests/Makefile.am (TESTS): Add test case.
43 ---
44 src/pch.c | 91 +++++++++++++++++++++++++++++++++++++++---------------
45 tests/Makefile.am | 1
46 tests/ed-style | 41 ++++++++++++++++++++++++
47 3 files changed, 108 insertions(+), 25 deletions(-)
49 --- a/src/pch.c
50 +++ b/src/pch.c
51 @@ -33,6 +33,7 @@
52 # include <io.h>
53 #endif
54 #include <safe.h>
55 +#include <sys/wait.h>
57 #define INITHUNKMAX 125 /* initial dynamic allocation size */
59 @@ -2389,24 +2390,28 @@ do_ed_script (char const *inname, char c
60 static char const editor_program[] = EDITOR_PROGRAM;
62 file_offset beginning_of_this_line;
63 - FILE *pipefp = 0;
64 size_t chars_read;
65 + FILE *tmpfp = 0;
66 + char const *tmpname;
67 + int tmpfd;
68 + pid_t pid;
70 + if (! dry_run && ! skip_rest_of_patch)
71 + {
72 + /* Write ed script to a temporary file. This causes ed to abort on
73 + invalid commands such as when line numbers or ranges exceed the
74 + number of available lines. When ed reads from a pipe, it rejects
75 + invalid commands and treats the next line as a new command, which
76 + can lead to arbitrary command execution. */
78 + tmpfd = make_tempfile (&tmpname, 'e', NULL, O_RDWR | O_BINARY, 0);
79 + if (tmpfd == -1)
80 + pfatal ("Can't create temporary file %s", quotearg (tmpname));
81 + tmpfp = fdopen (tmpfd, "w+b");
82 + if (! tmpfp)
83 + pfatal ("Can't open stream for file %s", quotearg (tmpname));
84 + }
86 - if (! dry_run && ! skip_rest_of_patch) {
87 - int exclusive = *outname_needs_removal ? 0 : O_EXCL;
88 - if (inerrno != ENOENT)
89 - {
90 - *outname_needs_removal = true;
91 - copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
92 - }
93 - sprintf (buf, "%s %s%s", editor_program,
94 - verbosity == VERBOSE ? "" : "- ",
95 - outname);
96 - fflush (stdout);
97 - pipefp = popen(buf, binary_transput ? "wb" : "w");
98 - if (!pipefp)
99 - pfatal ("Can't open pipe to %s", quotearg (buf));
101 for (;;) {
102 char ed_command_letter;
103 beginning_of_this_line = file_tell (pfp);
104 @@ -2417,14 +2422,14 @@ do_ed_script (char const *inname, char c
106 ed_command_letter = get_ed_command_letter (buf);
107 if (ed_command_letter) {
108 - if (pipefp)
109 - if (! fwrite (buf, sizeof *buf, chars_read, pipefp))
110 + if (tmpfp)
111 + if (! fwrite (buf, sizeof *buf, chars_read, tmpfp))
112 write_fatal ();
113 if (ed_command_letter != 'd' && ed_command_letter != 's') {
114 p_pass_comments_through = true;
115 while ((chars_read = get_line ()) != 0) {
116 - if (pipefp)
117 - if (! fwrite (buf, sizeof *buf, chars_read, pipefp))
118 + if (tmpfp)
119 + if (! fwrite (buf, sizeof *buf, chars_read, tmpfp))
120 write_fatal ();
121 if (chars_read == 2 && strEQ (buf, ".\n"))
122 break;
123 @@ -2437,13 +2442,49 @@ do_ed_script (char const *inname, char c
124 break;
127 - if (!pipefp)
128 + if (!tmpfp)
129 return;
130 - if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, pipefp) == 0
131 - || fflush (pipefp) != 0)
132 + if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, tmpfp) == 0
133 + || fflush (tmpfp) != 0)
134 write_fatal ();
135 - if (pclose (pipefp) != 0)
136 - fatal ("%s FAILED", editor_program);
138 + if (lseek (tmpfd, 0, SEEK_SET) == -1)
139 + pfatal ("Can't rewind to the beginning of file %s", quotearg (tmpname));
141 + if (! dry_run && ! skip_rest_of_patch) {
142 + int exclusive = *outname_needs_removal ? 0 : O_EXCL;
143 + *outname_needs_removal = true;
144 + if (inerrno != ENOENT)
146 + *outname_needs_removal = true;
147 + copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
149 + sprintf (buf, "%s %s%s", editor_program,
150 + verbosity == VERBOSE ? "" : "- ",
151 + outname);
152 + fflush (stdout);
154 + pid = fork();
155 + if (pid == -1)
156 + pfatal ("Can't fork");
157 + else if (pid == 0)
159 + dup2 (tmpfd, 0);
160 + execl ("/bin/sh", "sh", "-c", buf, (char *) 0);
161 + _exit (2);
163 + else
165 + int wstatus;
166 + if (waitpid (pid, &wstatus, 0) == -1
167 + || ! WIFEXITED (wstatus)
168 + || WEXITSTATUS (wstatus) != 0)
169 + fatal ("%s FAILED", editor_program);
173 + fclose (tmpfp);
174 + safe_unlink (tmpname);
176 if (ofp)
178 --- a/tests/Makefile.am
179 +++ b/tests/Makefile.am
180 @@ -32,6 +32,7 @@ TESTS = \
181 crlf-handling \
182 dash-o-append \
183 deep-directories \
184 + ed-style \
185 empty-files \
186 false-match \
187 fifo \
188 --- /dev/null
189 +++ b/tests/ed-style
190 @@ -0,0 +1,41 @@
191 +# Copyright (C) 2018 Free Software Foundation, Inc.
193 +# Copying and distribution of this file, with or without modification,
194 +# in any medium, are permitted without royalty provided the copyright
195 +# notice and this notice are preserved.
197 +. $srcdir/test-lib.sh
199 +require cat
200 +use_local_patch
201 +use_tmpdir
203 +# ==============================================================
205 +cat > ed1.diff <<EOF
207 +foo
209 +EOF
211 +check 'patch -e foo -i ed1.diff' <<EOF
212 +EOF
214 +check 'cat foo' <<EOF
215 +foo
216 +EOF
218 +cat > ed2.diff <<EOF
219 +1337a
220 +r !echo bar
222 +EOF
224 +check 'patch -e foo -i ed2.diff 2> /dev/null || echo "Status: $?"' <<EOF
226 +Status: 2
227 +EOF
229 +check 'cat foo' <<EOF
230 +foo
231 +EOF
232 From: Jean Delvare <jdelvare@suse.de>
233 Subject: Update tests/Makefile.in
234 Patch-mainline: no, temporary integration
235 References: bsc#1088420, savannah#53566, CVE-2018-1000156
237 Previous patch modifies tests/Makefile.am. Mirror the changes to
238 tests/Makefile.in so that we don't need automake.
240 tests/Makefile.in | 8 ++++++++
241 1 file changed, 8 insertions(+)
243 --- a/tests/Makefile.in
244 +++ b/tests/Makefile.in
245 @@ -1308,6 +1308,7 @@ TESTS = \
246 crlf-handling \
247 dash-o-append \
248 deep-directories \
249 + ed-style \
250 empty-files \
251 false-match \
252 fifo \
253 @@ -1638,6 +1639,13 @@ deep-directories.log: deep-directories
254 $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
255 --log-file $$b.log --trs-file $$b.trs \
256 $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
257 + "$$tst" $(AM_TESTS_FD_REDIRECT)
258 +ed-style.log: ed-style
259 + @p='ed-style'; \
260 + b='ed-style'; \
261 + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
262 + --log-file $$b.log --trs-file $$b.trs \
263 + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
264 "$$tst" $(AM_TESTS_FD_REDIRECT)
265 empty-files.log: empty-files
266 @p='empty-files'; \
267 From: Andreas Gruenbacher <agruen@gnu.org>
268 Date: Fri, 6 Apr 2018 19:36:15 +0200
269 Subject: Invoke ed directly instead of using the shell
270 Git-commit: 3fcd042d26d70856e826a42b5f93dc4854d80bf0
271 Patch-mainline: yes
272 References: bsc#1088420, savannah#53566, CVE-2018-1000156
274 * src/pch.c (do_ed_script): Invoke ed directly instead of using a shell
275 command to avoid quoting vulnerabilities.
277 src/pch.c | 6 ++----
278 1 file changed, 2 insertions(+), 4 deletions(-)
280 --- a/src/pch.c
281 +++ b/src/pch.c
282 @@ -2459,9 +2459,6 @@ do_ed_script (char const *inname, char c
283 *outname_needs_removal = true;
284 copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
286 - sprintf (buf, "%s %s%s", editor_program,
287 - verbosity == VERBOSE ? "" : "- ",
288 - outname);
289 fflush (stdout);
291 pid = fork();
292 @@ -2470,7 +2467,8 @@ do_ed_script (char const *inname, char c
293 else if (pid == 0)
295 dup2 (tmpfd, 0);
296 - execl ("/bin/sh", "sh", "-c", buf, (char *) 0);
297 + assert (outname[0] != '!' && outname[0] != '-');
298 + execlp (editor_program, editor_program, "-", outname, (char *) NULL);
299 _exit (2);
301 else
302 From: Andreas Gruenbacher <agruen@gnu.org>
303 Date: Fri, 6 Apr 2018 20:32:46 +0200
304 Subject: Minor cleanups in do_ed_script
305 Git-commit: 2a32bf09f5e9572da4be183bb0dbde8164351474
306 Patch-mainline: yes
307 References: bsc#1088420, savannah#53566, CVE-2018-1000156
309 * src/pch.c (do_ed_script): Minor cleanups.
311 Backporting notes: adjusted because we don't have commit ff1d3a67da1e
312 ("Use gnulib execute module") so the context is very different.
314 src/pch.c | 56 +++++++++++++++++++++++++++-----------------------------
315 1 file changed, 27 insertions(+), 29 deletions(-)
317 --- a/src/pch.c
318 +++ b/src/pch.c
319 @@ -2395,6 +2395,8 @@ do_ed_script (char const *inname, char c
320 char const *tmpname;
321 int tmpfd;
322 pid_t pid;
323 + int exclusive = *outname_needs_removal ? 0 : O_EXCL;
326 if (! dry_run && ! skip_rest_of_patch)
328 @@ -2442,7 +2444,7 @@ do_ed_script (char const *inname, char c
329 break;
332 - if (!tmpfp)
333 + if (dry_run || skip_rest_of_patch)
334 return;
335 if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, tmpfp) == 0
336 || fflush (tmpfp) != 0)
337 @@ -2451,35 +2453,31 @@ do_ed_script (char const *inname, char c
338 if (lseek (tmpfd, 0, SEEK_SET) == -1)
339 pfatal ("Can't rewind to the beginning of file %s", quotearg (tmpname));
341 - if (! dry_run && ! skip_rest_of_patch) {
342 - int exclusive = *outname_needs_removal ? 0 : O_EXCL;
343 + if (inerrno != ENOENT)
345 *outname_needs_removal = true;
346 - if (inerrno != ENOENT)
348 - *outname_needs_removal = true;
349 - copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
351 - fflush (stdout);
353 - pid = fork();
354 - if (pid == -1)
355 - pfatal ("Can't fork");
356 - else if (pid == 0)
358 - dup2 (tmpfd, 0);
359 - assert (outname[0] != '!' && outname[0] != '-');
360 - execlp (editor_program, editor_program, "-", outname, (char *) NULL);
361 - _exit (2);
363 - else
365 - int wstatus;
366 - if (waitpid (pid, &wstatus, 0) == -1
367 - || ! WIFEXITED (wstatus)
368 - || WEXITSTATUS (wstatus) != 0)
369 - fatal ("%s FAILED", editor_program);
372 + copy_file (inname, outname, 0, exclusive, instat.st_mode, true);
374 + fflush (stdout);
376 + pid = fork();
377 + if (pid == -1)
378 + pfatal ("Can't fork");
379 + else if (pid == 0)
381 + dup2 (tmpfd, 0);
382 + assert (outname[0] != '!' && outname[0] != '-');
383 + execlp (editor_program, editor_program, "-", outname, (char *) NULL);
384 + _exit (2);
386 + else
388 + int wstatus;
389 + if (waitpid (pid, &wstatus, 0) == -1
390 + || ! WIFEXITED (wstatus)
391 + || WEXITSTATUS (wstatus) != 0)
392 + fatal ("%s FAILED", editor_program);
395 fclose (tmpfp);
396 safe_unlink (tmpname);
397 From: Bruno Haible <bruno@clisp.org>
398 Date: Sat, 7 Apr 2018 12:34:03 +0200
399 Subject: Fix 'ed-style' test failure
400 Git-commit: 458ac51a05426c1af9aa6bf1342ecf60728c19b4
401 Patch-mainline: yes
402 References: bsc#1088420, savannah#53566, CVE-2018-1000156
404 * tests/ed-style: Remove '?' line from expected output.
406 tests/ed-style | 3 +--
407 1 file changed, 1 insertion(+), 2 deletions(-)
409 --- a/tests/ed-style
410 +++ b/tests/ed-style
411 @@ -31,8 +31,7 @@ r !echo bar
415 -check 'patch -e foo -i ed2.diff 2> /dev/null || echo "Status: $?"' <<EOF
417 +check 'patch -e foo -i ed2.diff > /dev/null 2> /dev/null || echo "Status: $?"' <<EOF
418 Status: 2
421 From: Jean Delvare <jdelvare@suse.de>
422 Date: Thu, 3 May 2018 14:31:55 +0200
423 Subject: Don't leak temporary file on failed ed-style patch
424 Git-commit: 19599883ffb6a450d2884f081f8ecf68edbed7ee
425 Patch-mainline: yes
426 References: bsc#1092500, savannah#53820
428 Now that we write ed-style patches to a temporary file before we
429 apply them, we need to ensure that the temporary file is removed
430 before we leave, even on fatal error.
432 * src/pch.c (do_ed_script): Use global TMPEDNAME instead of local
433 tmpname. Don't unlink the file directly, instead tag it for removal
434 at exit time.
435 * src/patch.c (cleanup): Unlink TMPEDNAME at exit.
437 This closes bug #53820:
438 https://savannah.gnu.org/bugs/index.php?53820
440 Fixes: 123eaff0d5d1 ("Fix arbitrary command execution in ed-style patches (CVE-2018-1000156)")
442 src/common.h | 2 ++
443 src/patch.c | 1 +
444 src/pch.c | 11 +++++------
445 3 files changed, 8 insertions(+), 6 deletions(-)
447 --- a/src/common.h
448 +++ b/src/common.h
449 @@ -94,10 +94,12 @@ XTERN char const *origsuff;
450 XTERN char const * TMPINNAME;
451 XTERN char const * TMPOUTNAME;
452 XTERN char const * TMPPATNAME;
453 +XTERN char const * TMPEDNAME;
455 XTERN bool TMPINNAME_needs_removal;
456 XTERN bool TMPOUTNAME_needs_removal;
457 XTERN bool TMPPATNAME_needs_removal;
458 +XTERN bool TMPEDNAME_needs_removal;
460 #ifdef DEBUGGING
461 XTERN int debug;
462 --- a/src/patch.c
463 +++ b/src/patch.c
464 @@ -1999,6 +1999,7 @@ cleanup (void)
465 remove_if_needed (TMPINNAME, &TMPINNAME_needs_removal);
466 remove_if_needed (TMPOUTNAME, &TMPOUTNAME_needs_removal);
467 remove_if_needed (TMPPATNAME, &TMPPATNAME_needs_removal);
468 + remove_if_needed (TMPEDNAME, &TMPEDNAME_needs_removal);
469 remove_if_needed (TMPREJNAME, &TMPREJNAME_needs_removal);
470 output_files (NULL);
472 --- a/src/pch.c
473 +++ b/src/pch.c
474 @@ -2392,7 +2392,6 @@ do_ed_script (char const *inname, char c
475 file_offset beginning_of_this_line;
476 size_t chars_read;
477 FILE *tmpfp = 0;
478 - char const *tmpname;
479 int tmpfd;
480 pid_t pid;
481 int exclusive = *outname_needs_removal ? 0 : O_EXCL;
482 @@ -2406,12 +2405,13 @@ do_ed_script (char const *inname, char c
483 invalid commands and treats the next line as a new command, which
484 can lead to arbitrary command execution. */
486 - tmpfd = make_tempfile (&tmpname, 'e', NULL, O_RDWR | O_BINARY, 0);
487 + tmpfd = make_tempfile (&TMPEDNAME, 'e', NULL, O_RDWR | O_BINARY, 0);
488 if (tmpfd == -1)
489 - pfatal ("Can't create temporary file %s", quotearg (tmpname));
490 + pfatal ("Can't create temporary file %s", quotearg (TMPEDNAME));
491 + TMPEDNAME_needs_removal = true;
492 tmpfp = fdopen (tmpfd, "w+b");
493 if (! tmpfp)
494 - pfatal ("Can't open stream for file %s", quotearg (tmpname));
495 + pfatal ("Can't open stream for file %s", quotearg (TMPEDNAME));
498 for (;;) {
499 @@ -2451,7 +2451,7 @@ do_ed_script (char const *inname, char c
500 write_fatal ();
502 if (lseek (tmpfd, 0, SEEK_SET) == -1)
503 - pfatal ("Can't rewind to the beginning of file %s", quotearg (tmpname));
504 + pfatal ("Can't rewind to the beginning of file %s", quotearg (TMPEDNAME));
506 if (inerrno != ENOENT)
508 @@ -2480,7 +2480,6 @@ do_ed_script (char const *inname, char c
511 fclose (tmpfp);
512 - safe_unlink (tmpname);
514 if (ofp)
516 From: Jean Delvare <jdelvare@suse.de>
517 Date: Mon, 7 May 2018 15:14:45 +0200
518 Subject: Don't leak temporary file on failed multi-file ed-style patch
519 Git-commit: 369dcccdfa6336e5a873d6d63705cfbe04c55727
520 Patch-mainline: yes
521 References: bsc#1092500, savannah#53820
523 The previous fix worked fine with single-file ed-style patches, but
524 would still leak temporary files in the case of multi-file ed-style
525 patch. Fix that case as well, and extend the test case to check for
528 * src/patch.c (main): Unlink TMPEDNAME if needed before moving to
529 the next file in a patch.
531 This closes bug #53820:
532 https://savannah.gnu.org/bugs/index.php?53820
534 Fixes: 123eaff0d5d1 ("Fix arbitrary command execution in ed-style patches (CVE-2018-1000156)")
535 Fixes: 19599883ffb6 ("Don't leak temporary file on failed ed-style patch")
537 src/patch.c | 1 +
538 tests/ed-style | 31 +++++++++++++++++++++++++++++++
539 2 files changed, 32 insertions(+)
541 --- a/src/patch.c
542 +++ b/src/patch.c
543 @@ -236,6 +236,7 @@ main (int argc, char **argv)
545 remove_if_needed (TMPOUTNAME, &TMPOUTNAME_needs_removal);
547 + remove_if_needed (TMPEDNAME, &TMPEDNAME_needs_removal);
549 if (! skip_rest_of_patch && ! file_type)
551 --- a/tests/ed-style
552 +++ b/tests/ed-style
553 @@ -38,3 +38,34 @@ EOF
554 check 'cat foo' <<EOF
558 +# Test the case where one ed-style patch modifies several files
560 +cat > ed3.diff <<EOF
561 +--- foo
562 ++++ foo
564 +bar
566 +--- baz
567 ++++ baz
569 +baz
571 +EOF
573 +# Apparently we can't create a file with such a patch, while it works fine
574 +# when the file name is provided on the command line
575 +cat > baz <<EOF
576 +EOF
578 +check 'patch -e -i ed3.diff' <<EOF
579 +EOF
581 +check 'cat foo' <<EOF
582 +bar
583 +EOF
585 +check 'cat baz' <<EOF
586 +baz
587 +EOF