commit 4bc1354d6c8696ffaf94ce5218451e62116777b2 Author: overweight <5324761+overweight@user.noreply.gitee.com> Date: Mon Sep 30 11:11:23 2019 -0400 Package init diff --git a/CVE-2018-6951.patch b/CVE-2018-6951.patch new file mode 100644 index 0000000..22d5f06 --- /dev/null +++ b/CVE-2018-6951.patch @@ -0,0 +1,28 @@ +From f290f48a621867084884bfff87f8093c15195e6a Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Mon, 12 Feb 2018 16:48:24 +0100 +Subject: Fix segfault with mangled rename patch + +http://savannah.gnu.org/bugs/?53132 +* src/pch.c (intuit_diff_type): Ensure that two filenames are specified +for renames and copies (fix the existing check). +--- + src/pch.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/pch.c b/src/pch.c +index ff9ed2c..bc6278c 100644 +--- a/src/pch.c ++++ b/src/pch.c +@@ -974,7 +974,8 @@ intuit_diff_type (bool need_header, mode_t *p_file_type) + if ((pch_rename () || pch_copy ()) + && ! inname + && ! ((i == OLD || i == NEW) && +- p_name[! reverse] && ++ p_name[reverse] && p_name[! reverse] && ++ name_is_valid (p_name[reverse]) && + name_is_valid (p_name[! reverse]))) + { + say ("Cannot %s file without two valid file names\n", pch_rename () ? "rename" : "copy"); +-- +cgit v1.0-41-gc330 diff --git a/Don-t-leak-temporary-file-on-failed-ed-style-patch.patch b/Don-t-leak-temporary-file-on-failed-ed-style-patch.patch new file mode 100644 index 0000000..389ba15 --- /dev/null +++ b/Don-t-leak-temporary-file-on-failed-ed-style-patch.patch @@ -0,0 +1,103 @@ +From 19599883ffb6a450d2884f081f8ecf68edbed7ee Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Thu, 3 May 2018 14:31:55 +0200 +Subject: [PATCH 14/17] Don't leak temporary file on failed ed-style patch + +Now that we write ed-style patches to a temporary file before we +apply them, we need to ensure that the temporary file is removed +before we leave, even on fatal error. + +* src/pch.c (do_ed_script): Use global TMPEDNAME instead of local + tmpname. Don't unlink the file directly, instead tag it for removal + at exit time. +* src/patch.c (cleanup): Unlink TMPEDNAME at exit. + +This closes bug #53820: +https://savannah.gnu.org/bugs/index.php?53820 + +Fixes: 123eaff0d5d1 ("Fix arbitrary command execution in ed-style patches (CVE-2018-1000156)") +--- + src/common.h | 2 ++ + src/patch.c | 1 + + src/pch.c | 11 +++++------ + 3 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/src/common.h b/src/common.h +index 904a3f8..53c5e32 100644 +--- a/src/common.h ++++ b/src/common.h +@@ -94,10 +94,12 @@ XTERN char const *origsuff; + XTERN char const * TMPINNAME; + XTERN char const * TMPOUTNAME; + XTERN char const * TMPPATNAME; ++XTERN char const * TMPEDNAME; + + XTERN bool TMPINNAME_needs_removal; + XTERN bool TMPOUTNAME_needs_removal; + XTERN bool TMPPATNAME_needs_removal; ++XTERN bool TMPEDNAME_needs_removal; + + #ifdef DEBUGGING + XTERN int debug; +diff --git a/src/patch.c b/src/patch.c +index 3fcaec5..9146597 100644 +--- a/src/patch.c ++++ b/src/patch.c +@@ -1999,6 +1999,7 @@ cleanup (void) + remove_if_needed (TMPINNAME, &TMPINNAME_needs_removal); + remove_if_needed (TMPOUTNAME, &TMPOUTNAME_needs_removal); + remove_if_needed (TMPPATNAME, &TMPPATNAME_needs_removal); ++ remove_if_needed (TMPEDNAME, &TMPEDNAME_needs_removal); + remove_if_needed (TMPREJNAME, &TMPREJNAME_needs_removal); + output_files (NULL); + } +diff --git a/src/pch.c b/src/pch.c +index 79a3c99..1bb3153 100644 +--- a/src/pch.c ++++ b/src/pch.c +@@ -2403,7 +2403,6 @@ do_ed_script (char const *inname, char c + file_offset beginning_of_this_line; + size_t chars_read; + FILE *tmpfp = 0; +- char const *tmpname; + int tmpfd = -1; + pid_t pid; + +@@ -2415,12 +2414,13 @@ do_ed_script (char const *inname, char c + invalid commands and treats the next line as a new command, which + can lead to arbitrary command execution. */ + +- tmpfd = make_tempfile (&tmpname, 'e', NULL, O_RDWR | O_BINARY, 0); ++ tmpfd = make_tempfile (&TMPEDNAME, 'e', NULL, O_RDWR | O_BINARY, 0); + if (tmpfd == -1) +- pfatal ("Can't create temporary file %s", quotearg (tmpname)); ++ pfatal ("Can't create temporary file %s", quotearg (TMPEDNAME)); ++ TMPEDNAME_needs_removal = true; + tmpfp = fdopen (tmpfd, "w+b"); + if (! tmpfp) +- pfatal ("Can't open stream for file %s", quotearg (tmpname)); ++ pfatal ("Can't open stream for file %s", quotearg (TMPEDNAME)); + } + + for (;;) { +@@ -2461,7 +2461,7 @@ do_ed_script (char const *inname, char c + write_fatal (); + + if (lseek (tmpfd, 0, SEEK_SET) == -1) +- pfatal ("Can't rewind to the beginning of file %s", quotearg (tmpname)); ++ pfatal ("Can't rewind to the beginning of file %s", quotearg (TMPEDNAME)); + + if (! dry_run && ! skip_rest_of_patch) { + int exclusive = *outname_needs_removal ? 0 : O_EXCL; +@@ -2496,8 +2496,6 @@ do_ed_script (char const *inname, char c + } + + fclose (tmpfp); +- unlink (tmpname); +- free((char*) tmpname); + + if (ofp) + { +-- +2.19.1 + diff --git a/Don-t-leak-temporary-file-on-failed-multi-file-ed-st.patch b/Don-t-leak-temporary-file-on-failed-multi-file-ed-st.patch new file mode 100644 index 0000000..73e256f --- /dev/null +++ b/Don-t-leak-temporary-file-on-failed-multi-file-ed-st.patch @@ -0,0 +1,78 @@ +From 369dcccdfa6336e5a873d6d63705cfbe04c55727 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Mon, 7 May 2018 15:14:45 +0200 +Subject: [PATCH 15/17] Don't leak temporary file on failed multi-file ed-style + patch + +The previous fix worked fine with single-file ed-style patches, but +would still leak temporary files in the case of multi-file ed-style +patch. Fix that case as well, and extend the test case to check for +it. + +* src/patch.c (main): Unlink TMPEDNAME if needed before moving to + the next file in a patch. + +This closes bug #53820: +https://savannah.gnu.org/bugs/index.php?53820 + +Fixes: 123eaff0d5d1 ("Fix arbitrary command execution in ed-style patches (CVE-2018-1000156)") +Fixes: 19599883ffb6 ("Don't leak temporary file on failed ed-style patch") +--- + src/patch.c | 1 + + tests/ed-style | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 32 insertions(+) + +diff --git a/src/patch.c b/src/patch.c +index 9146597..81c7a02 100644 +--- a/src/patch.c ++++ b/src/patch.c +@@ -236,6 +236,7 @@ main (int argc, char **argv) + } + remove_if_needed (TMPOUTNAME, &TMPOUTNAME_needs_removal); + } ++ remove_if_needed (TMPEDNAME, &TMPEDNAME_needs_removal); + + if (! skip_rest_of_patch && ! file_type) + { +diff --git a/tests/ed-style b/tests/ed-style +index 6b6ef9d..504e6e5 100644 +--- a/tests/ed-style ++++ b/tests/ed-style +@@ -38,3 +38,34 @@ EOF + check 'cat foo' < ed3.diff < baz < +Date: Sat, 7 Apr 2018 12:21:04 +0200 +Subject: [PATCH 11/17] Fix check of return value of fwrite(). + +* src/patch.c (copy_till): Consider incomplete fwrite() write as an error. +* src/pch.c (pch_write_line, do_ed_script): Likewise. +--- + src/patch.c | 4 ++-- + src/pch.c | 14 +++++++++----- + 2 files changed, 11 insertions(+), 7 deletions(-) + +diff --git a/src/patch.c b/src/patch.c +index 1ae91d9..3fcaec5 100644 +--- a/src/patch.c ++++ b/src/patch.c +@@ -2,7 +2,7 @@ + + /* Copyright (C) 1984, 1985, 1986, 1987, 1988 Larry Wall + +- Copyright (C) 1989-1993, 1997-1999, 2002-2003, 2006, 2009-2012 Free Software ++ Copyright (C) 1989-1993, 1997-1999, 2002-2003, 2006, 2009-2018 Free Software + Foundation, Inc. + + This program is free software: you can redistribute it and/or modify +@@ -1641,7 +1641,7 @@ copy_till (struct outstate *outstate, lin lastline) + if (size) + { + if ((! outstate->after_newline && putc ('\n', fp) == EOF) +- || ! fwrite (s, sizeof *s, size, fp)) ++ || fwrite (s, sizeof *s, size, fp) < size) + write_fatal (); + outstate->after_newline = s[size - 1] == '\n'; + outstate->zero_output = false; +diff --git a/src/pch.c b/src/pch.c +index cda3dfa..79a3c99 100644 +--- a/src/pch.c ++++ b/src/pch.c +@@ -2279,8 +2279,11 @@ pfetch (lin line) + bool + pch_write_line (lin line, FILE *file) + { +- bool after_newline = (p_len[line] > 0) && (p_line[line][p_len[line] - 1] == '\n'); +- if (! fwrite (p_line[line], sizeof (*p_line[line]), p_len[line], file)) ++ bool after_newline = ++ (p_len[line] > 0) && (p_line[line][p_len[line] - 1] == '\n'); ++ ++ if (fwrite (p_line[line], sizeof (*p_line[line]), p_len[line], file) ++ < p_len[line]) + write_fatal (); + return after_newline; + } +@@ -2427,13 +2430,14 @@ do_ed_script (char const *inname, char const *outname, + ed_command_letter = get_ed_command_letter (buf); + if (ed_command_letter) { + if (tmpfp) +- if (! fwrite (buf, sizeof *buf, chars_read, tmpfp)) ++ if (fwrite (buf, sizeof *buf, chars_read, tmpfp) < chars_read) + write_fatal (); + if (ed_command_letter != 'd' && ed_command_letter != 's') { + p_pass_comments_through = true; + while ((chars_read = get_line ()) != 0) { + if (tmpfp) +- if (! fwrite (buf, sizeof *buf, chars_read, tmpfp)) ++ if (fwrite (buf, sizeof *buf, chars_read, tmpfp) ++ < chars_read) + write_fatal (); + if (chars_read == 2 && strEQ (buf, ".\n")) + break; +@@ -2448,7 +2452,7 @@ do_ed_script (char const *inname, char const *outname, + } + if (!tmpfp) + return; +- if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, tmpfp) == 0 ++ if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, tmpfp) < (size_t) 4 + || fflush (tmpfp) != 0) + write_fatal (); + +-- +2.19.1 + diff --git a/Fix-swapping-fake-lines-in-pch_swap.patch b/Fix-swapping-fake-lines-in-pch_swap.patch new file mode 100644 index 0000000..7b2cbbb --- /dev/null +++ b/Fix-swapping-fake-lines-in-pch_swap.patch @@ -0,0 +1,30 @@ +From 9c986353e420ead6e706262bf204d6e03322c300 Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Fri, 17 Aug 2018 13:35:40 +0200 +Subject: [PATCH 17/17] Fix swapping fake lines in pch_swap + +* src/pch.c (pch_swap): Fix swapping p_bfake and p_efake when there is a +blank line in the middle of a context-diff hunk: that empty line stays +in the middle of the hunk and isn't swapped. + +Fixes: https://savannah.gnu.org/bugs/index.php?53133 +--- + src/pch.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/pch.c b/src/pch.c +index e92bc64..a500ad9 100644 +--- a/src/pch.c ++++ b/src/pch.c +@@ -2122,7 +2122,7 @@ pch_swap (void) + } + if (p_efake >= 0) { /* fix non-freeable ptr range */ + if (p_efake <= i) +- n = p_end - i + 1; ++ n = p_end - p_ptrn_lines; + else + n = -i; + p_efake += n; +-- +2.19.1 + diff --git a/patch-2.7.6.tar.xz b/patch-2.7.6.tar.xz new file mode 100644 index 0000000..ae89c9f Binary files /dev/null and b/patch-2.7.6.tar.xz differ diff --git a/patch-CVE-2018-1000156.patch b/patch-CVE-2018-1000156.patch new file mode 100644 index 0000000..fc3b0c2 --- /dev/null +++ b/patch-CVE-2018-1000156.patch @@ -0,0 +1,209 @@ +diff -up patch-2.7.6/src/pch.c.CVE-2018-1000156 patch-2.7.6/src/pch.c +--- patch-2.7.6/src/pch.c.CVE-2018-1000156 2018-02-03 12:41:49.000000000 +0000 ++++ patch-2.7.6/src/pch.c 2018-05-03 12:50:43.374036905 +0100 +@@ -33,6 +33,7 @@ + # include + #endif + #include ++#include + + #define INITHUNKMAX 125 /* initial dynamic allocation size */ + +@@ -2388,22 +2389,28 @@ do_ed_script (char const *inname, char c + static char const editor_program[] = EDITOR_PROGRAM; + + file_offset beginning_of_this_line; +- FILE *pipefp = 0; + size_t chars_read; ++ FILE *tmpfp = 0; ++ char const *tmpname; ++ int tmpfd = -1; ++ pid_t pid; ++ ++ if (! dry_run && ! skip_rest_of_patch) ++ { ++ /* Write ed script to a temporary file. This causes ed to abort on ++ invalid commands such as when line numbers or ranges exceed the ++ number of available lines. When ed reads from a pipe, it rejects ++ invalid commands and treats the next line as a new command, which ++ can lead to arbitrary command execution. */ ++ ++ tmpfd = make_tempfile (&tmpname, 'e', NULL, O_RDWR | O_BINARY, 0); ++ if (tmpfd == -1) ++ pfatal ("Can't create temporary file %s", quotearg (tmpname)); ++ tmpfp = fdopen (tmpfd, "w+b"); ++ if (! tmpfp) ++ pfatal ("Can't open stream for file %s", quotearg (tmpname)); ++ } + +- if (! dry_run && ! skip_rest_of_patch) { +- int exclusive = *outname_needs_removal ? 0 : O_EXCL; +- assert (! inerrno); +- *outname_needs_removal = true; +- copy_file (inname, outname, 0, exclusive, instat.st_mode, true); +- sprintf (buf, "%s %s%s", editor_program, +- verbosity == VERBOSE ? "" : "- ", +- outname); +- fflush (stdout); +- pipefp = popen(buf, binary_transput ? "wb" : "w"); +- if (!pipefp) +- pfatal ("Can't open pipe to %s", quotearg (buf)); +- } + for (;;) { + char ed_command_letter; + beginning_of_this_line = file_tell (pfp); +@@ -2414,14 +2421,14 @@ do_ed_script (char const *inname, char c + } + ed_command_letter = get_ed_command_letter (buf); + if (ed_command_letter) { +- if (pipefp) +- if (! fwrite (buf, sizeof *buf, chars_read, pipefp)) ++ if (tmpfp) ++ if (! fwrite (buf, sizeof *buf, chars_read, tmpfp)) + write_fatal (); + if (ed_command_letter != 'd' && ed_command_letter != 's') { + p_pass_comments_through = true; + while ((chars_read = get_line ()) != 0) { +- if (pipefp) +- if (! fwrite (buf, sizeof *buf, chars_read, pipefp)) ++ if (tmpfp) ++ if (! fwrite (buf, sizeof *buf, chars_read, tmpfp)) + write_fatal (); + if (chars_read == 2 && strEQ (buf, ".\n")) + break; +@@ -2434,13 +2441,50 @@ do_ed_script (char const *inname, char c + break; + } + } +- if (!pipefp) ++ if (!tmpfp) + return; +- if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, pipefp) == 0 +- || fflush (pipefp) != 0) ++ if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, tmpfp) == 0 ++ || fflush (tmpfp) != 0) + write_fatal (); +- if (pclose (pipefp) != 0) +- fatal ("%s FAILED", editor_program); ++ ++ if (lseek (tmpfd, 0, SEEK_SET) == -1) ++ pfatal ("Can't rewind to the beginning of file %s", quotearg (tmpname)); ++ ++ if (! dry_run && ! skip_rest_of_patch) { ++ int exclusive = *outname_needs_removal ? 0 : O_EXCL; ++ *outname_needs_removal = true; ++ if (inerrno != ENOENT) ++ { ++ *outname_needs_removal = true; ++ copy_file (inname, outname, 0, exclusive, instat.st_mode, true); ++ } ++ sprintf (buf, "%s %s%s", editor_program, ++ verbosity == VERBOSE ? "" : "- ", ++ outname); ++ fflush (stdout); ++ ++ pid = fork(); ++ if (pid == -1) ++ pfatal ("Can't fork"); ++ else if (pid == 0) ++ { ++ dup2 (tmpfd, 0); ++ execl ("/bin/sh", "sh", "-c", buf, (char *) 0); ++ _exit (2); ++ } ++ else ++ { ++ int wstatus; ++ if (waitpid (pid, &wstatus, 0) == -1 ++ || ! WIFEXITED (wstatus) ++ || WEXITSTATUS (wstatus) != 0) ++ fatal ("%s FAILED", editor_program); ++ } ++ } ++ ++ fclose (tmpfp); ++ unlink (tmpname); ++ free((char*) tmpname); + + if (ofp) + { +diff -up patch-2.7.6/tests/ed-style.CVE-2018-1000156 patch-2.7.6/tests/ed-style +--- patch-2.7.6/tests/ed-style.CVE-2018-1000156 2018-05-03 12:50:28.988937938 +0100 ++++ patch-2.7.6/tests/ed-style 2018-05-03 12:51:35.841397873 +0100 +@@ -0,0 +1,40 @@ ++# Copyright (C) 2018 Free Software Foundation, Inc. ++# ++# Copying and distribution of this file, with or without modification, ++# in any medium, are permitted without royalty provided the copyright ++# notice and this notice are preserved. ++ ++. $srcdir/test-lib.sh ++ ++require_cat ++use_local_patch ++use_tmpdir ++ ++# ============================================================== ++ ++cat > ed1.diff < ed2.diff < /dev/null 2> /dev/null || echo "Status: $?"' < + #include + ++#include ++ + #include + + #include +@@ -84,6 +86,7 @@ XTERN char *outfile; + XTERN int inerrno; + XTERN int invc; + XTERN struct stat instat; ++XTERN security_context_t incontext; + XTERN bool dry_run; + XTERN bool posixly_correct; + +diff -up patch-2.7.6/src/inp.c.selinux patch-2.7.6/src/inp.c +--- patch-2.7.6/src/inp.c.selinux 2017-09-04 12:34:16.000000000 +0100 ++++ patch-2.7.6/src/inp.c 2018-02-12 12:29:44.415225377 +0000 +@@ -145,7 +145,7 @@ get_input_file (char const *filename, ch + char *getbuf; + + if (inerrno == -1) +- inerrno = stat_file (filename, &instat); ++ inerrno = stat_file (filename, &instat, &incontext); + + /* Perhaps look for RCS or SCCS versions. */ + if (S_ISREG (file_type) +@@ -190,7 +190,7 @@ get_input_file (char const *filename, ch + } + + if (cs && version_get (filename, cs, ! inerrno, elsewhere, getbuf, +- &instat)) ++ &instat, &incontext)) + inerrno = 0; + + free (getbuf); +@@ -201,6 +201,7 @@ get_input_file (char const *filename, ch + { + instat.st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; + instat.st_size = 0; ++ incontext = NULL; + } + else if (! ((S_ISREG (file_type) || S_ISLNK (file_type)) + && (file_type & S_IFMT) == (instat.st_mode & S_IFMT))) +diff -up patch-2.7.6/src/Makefile.am.selinux patch-2.7.6/src/Makefile.am +--- patch-2.7.6/src/Makefile.am.selinux 2017-09-04 12:34:16.000000000 +0100 ++++ patch-2.7.6/src/Makefile.am 2018-02-12 12:29:44.415225377 +0000 +@@ -37,7 +37,7 @@ patch_SOURCES = \ + + AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib + patch_LDADD = $(LDADD) $(top_builddir)/lib/libpatch.a $(LIB_CLOCK_GETTIME) \ +- $(LIB_XATTR) $(LIB_EACCESS) ++ $(LIB_XATTR) $(LIB_EACCESS) -lselinux + + if ENABLE_MERGE + patch_SOURCES += merge.c +diff -up patch-2.7.6/src/Makefile.in.selinux patch-2.7.6/src/Makefile.in +--- patch-2.7.6/src/Makefile.in.selinux 2018-02-03 13:33:56.000000000 +0000 ++++ patch-2.7.6/src/Makefile.in 2018-02-12 12:29:44.415225377 +0000 +@@ -1147,7 +1147,7 @@ patch_SOURCES = bestmatch.h common.h inp + AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib \ + $(am__append_2) + patch_LDADD = $(LDADD) $(top_builddir)/lib/libpatch.a $(LIB_CLOCK_GETTIME) \ +- $(LIB_XATTR) $(LIB_EACCESS) ++ $(LIB_XATTR) $(LIB_EACCESS) -lselinux + + all: all-am + +diff -up patch-2.7.6/src/patch.c.selinux patch-2.7.6/src/patch.c +--- patch-2.7.6/src/patch.c.selinux 2018-02-03 12:41:49.000000000 +0000 ++++ patch-2.7.6/src/patch.c 2018-02-12 12:30:27.315164138 +0000 +@@ -269,19 +269,19 @@ main (int argc, char **argv) + if (! strcmp (inname, outname)) + { + if (inerrno == -1) +- inerrno = stat_file (inname, &instat); ++ inerrno = stat_file (inname, &instat, NULL); + outstat = instat; + outerrno = inerrno; + } + else +- outerrno = stat_file (outname, &outstat); ++ outerrno = stat_file (outname, &outstat, NULL); + + if (! outerrno) + { + if (has_queued_output (&outstat)) + { + output_files (&outstat); +- outerrno = stat_file (outname, &outstat); ++ outerrno = stat_file (outname, &outstat, NULL); + inerrno = -1; + } + if (! outerrno) +@@ -598,7 +598,7 @@ main (int argc, char **argv) + } + else + { +- attr |= FA_IDS | FA_MODE | FA_XATTRS; ++ attr |= FA_IDS | FA_MODE | FA_XATTRS | FA_SECCONTEXT; + set_file_attributes (TMPOUTNAME, attr, inname, &instat, + mode, &new_time); + } +@@ -658,7 +658,7 @@ main (int argc, char **argv) + struct stat oldst; + int olderrno; + +- olderrno = stat_file (rej, &oldst); ++ olderrno = stat_file (rej, &oldst, NULL); + if (olderrno && olderrno != ENOENT) + write_fatal (); + if (! olderrno && lookup_file_id (&oldst) == CREATED) +@@ -1790,7 +1790,7 @@ delete_file_later (const char *name, con + + if (! st) + { +- if (stat_file (name, &st_tmp) != 0) ++ if (stat_file (name, &st_tmp, NULL) != 0) + pfatal ("Can't get file attributes of %s %s", "file", name); + st = &st_tmp; + } +diff -up patch-2.7.6/src/pch.c.selinux patch-2.7.6/src/pch.c +--- patch-2.7.6/src/pch.c.selinux 2018-02-03 12:41:49.000000000 +0000 ++++ patch-2.7.6/src/pch.c 2018-02-12 12:29:44.416225375 +0000 +@@ -1,6 +1,6 @@ + /* reading patches */ + +-/* Copyright (C) 1986, 1987, 1988 Larry Wall ++/* Copyright (C) 1986, 1987, 1988, 2012 Larry Wall + + Copyright (C) 1990-1993, 1997-2003, 2006, 2009-2012 Free Software + Foundation, Inc. +@@ -296,7 +296,7 @@ there_is_another_patch (bool need_header + if (t > buf + 1 && *(t - 1) == '\n') + { + inname = xmemdup0 (buf, t - buf - 1); +- inerrno = stat_file (inname, &instat); ++ inerrno = stat_file (inname, &instat, &incontext); + if (inerrno) + { + perror (inname); +@@ -433,6 +433,7 @@ intuit_diff_type (bool need_header, mode + bool extended_headers = false; + enum nametype i; + struct stat st[3]; ++ security_context_t con[3]; + int stat_errno[3]; + int version_controlled[3]; + enum diff retval; +@@ -473,6 +474,7 @@ intuit_diff_type (bool need_header, mode + version_controlled[OLD] = -1; + version_controlled[NEW] = -1; + version_controlled[INDEX] = -1; ++ con[OLD] = con[NEW] = con[INDEX] = NULL; + p_rfc934_nesting = 0; + p_timestamp[OLD].tv_sec = p_timestamp[NEW].tv_sec = -1; + p_says_nonexistent[OLD] = p_says_nonexistent[NEW] = 0; +@@ -883,7 +885,7 @@ intuit_diff_type (bool need_header, mode + } + else + { +- stat_errno[i] = stat_file (p_name[i], &st[i]); ++ stat_errno[i] = stat_file (p_name[i], &st[i], &con[i]); + if (! stat_errno[i]) + { + if (lookup_file_id (&st[i]) == DELETE_LATER) +@@ -922,7 +924,7 @@ intuit_diff_type (bool need_header, mode + if (cs) + { + if (version_get (p_name[i], cs, false, readonly, +- getbuf, &st[i])) ++ getbuf, &st[i], &con[i])) + stat_errno[i] = 0; + else + version_controlled[i] = 0; +@@ -985,7 +987,7 @@ intuit_diff_type (bool need_header, mode + { + if (inname) + { +- inerrno = stat_file (inname, &instat); ++ inerrno = stat_file (inname, &instat, &incontext); + if (inerrno || (instat.st_mode & S_IFMT) == file_type) + maybe_reverse (inname, inerrno, inerrno || instat.st_size == 0); + } +@@ -998,8 +1000,14 @@ intuit_diff_type (bool need_header, mode + inerrno = stat_errno[i]; + invc = version_controlled[i]; + instat = st[i]; ++ incontext = con[i]; ++ con[i] = NULL; + } + ++ for (i = OLD; i <= INDEX; i++) ++ if (con[i]) ++ freecon (con[i]); ++ + return retval; + } + +diff -up patch-2.7.6/src/util.c.selinux patch-2.7.6/src/util.c +--- patch-2.7.6/src/util.c.selinux 2018-02-03 12:41:49.000000000 +0000 ++++ patch-2.7.6/src/util.c 2018-02-12 12:29:44.417225374 +0000 +@@ -300,6 +300,23 @@ set_file_attributes (char const *to, enu + S_ISLNK (mode) ? "symbolic link" : "file", + quotearg (to)); + } ++ if (attr & FA_SECCONTEXT) ++ { ++ security_context_t outcontext; ++ if (incontext && getfilecon (to, &outcontext) != -1 && outcontext) ++ { ++ if (strcmp (outcontext, incontext) && ++ setfilecon (to, incontext) != 0) ++ { ++ freecon (outcontext); ++ if (errno != ENOTSUP && errno != EPERM) ++ pfatal ("Can't set security context on file %s", ++ quotearg (to)); ++ } ++ else ++ freecon (outcontext); ++ } ++ } + } + + static void +@@ -446,7 +463,7 @@ move_file (char const *from, bool *from_ + struct stat to_st; + int to_errno; + +- to_errno = stat_file (to, &to_st); ++ to_errno = stat_file (to, &to_st, NULL); + if (backup) + create_backup (to, to_errno ? NULL : &to_st, false); + if (! to_errno) +@@ -818,7 +835,8 @@ version_controller (char const *filename + Return true if successful. */ + bool + version_get (char const *filename, char const *cs, bool exists, bool readonly, +- char const *getbuf, struct stat *filestat) ++ char const *getbuf, struct stat *filestat, ++ security_context_t *filecontext) + { + if (patch_get < 0) + { +@@ -843,6 +861,13 @@ version_get (char const *filename, char + fatal ("Can't get file %s from %s", quotearg (filename), cs); + if (safe_stat (filename, filestat) != 0) + pfatal ("%s", quotearg (filename)); ++ if (filecontext && getfilecon (filename, filecontext) == -1) ++ { ++ if (errno == ENODATA || errno == ENOTSUP) ++ *filecontext = NULL; ++ else ++ pfatal ("%s", quotearg (filename)); ++ } + } + + return 1; +@@ -1670,12 +1695,28 @@ make_tempfile (char const **name, char l + return fd; + } + +-int stat_file (char const *filename, struct stat *st) ++int stat_file (char const *filename, struct stat *st, security_context_t *con) + { + int (*xstat)(char const *, struct stat *) = + follow_symlinks ? safe_stat : safe_lstat; ++ int (*xgetfilecon)(char const *, security_context_t *) = ++ follow_symlinks ? getfilecon : lgetfilecon; ++ ++ if (xstat (filename, st) == 0) ++ { ++ if (con) ++ { ++ if (xgetfilecon (filename, con) != -1 || ++ errno == ENODATA || errno == ENOTSUP) ++ return 0; + +- return xstat (filename, st) == 0 ? 0 : errno; ++ *con = NULL; ++ } ++ else ++ return 0; ++ } ++ ++ return errno; + } + + /* Check if a filename is relative and free of ".." components. +diff -up patch-2.7.6/src/util.h.selinux patch-2.7.6/src/util.h +--- patch-2.7.6/src/util.h.selinux 2018-02-03 12:41:49.000000000 +0000 ++++ patch-2.7.6/src/util.h 2018-02-12 12:30:08.533190949 +0000 +@@ -44,7 +44,7 @@ char *parse_name (char const *, int, cha + char *savebuf (char const *, size_t); + char *savestr (char const *); + char const *version_controller (char const *, bool, struct stat const *, char **, char **); +-bool version_get (char const *, char const *, bool, bool, char const *, struct stat *); ++bool version_get (char const *, char const *, bool, bool, char const *, struct stat *, security_context_t *); + int create_file (char const *, int, mode_t, bool); + int systemic (char const *); + char *format_linenum (char[LINENUM_LENGTH_BOUND + 1], lin); +@@ -67,7 +67,7 @@ void insert_file_id (struct stat const * + enum file_id_type lookup_file_id (struct stat const *); + void set_queued_output (struct stat const *, bool); + bool has_queued_output (struct stat const *); +-int stat_file (char const *, struct stat *); ++int stat_file (char const *, struct stat *, security_context_t *); + bool filename_is_safe (char const *) _GL_ATTRIBUTE_PURE; + bool cwd_is_root (char const *); + +@@ -75,7 +75,8 @@ enum file_attributes { + FA_TIMES = 1, + FA_IDS = 2, + FA_MODE = 4, +- FA_XATTRS = 8 ++ FA_XATTRS = 8, ++ FA_SECCONTEXT = 16 + }; + + void set_file_attributes (char const *, enum file_attributes, char const *, diff --git a/patch.spec b/patch.spec new file mode 100644 index 0000000..cb29819 --- /dev/null +++ b/patch.spec @@ -0,0 +1,59 @@ +Name: patch +Version: 2.7.6 +Release: 6 +Summary: Utiliity which applies a patch file to original files. +License: GPLv3+ +URL: http://www.gnu.org/software/patch/patch.html +Source0: https://ftp.gnu.org/gnu/patch/patch-%{version}.tar.xz +Patch0: patch-CVE-2018-1000156.patch +Patch1: patch-selinux.patch +Patch6000: CVE-2018-6951.patch +Patch6001: Fix-check-of-return-value-of-fwrite.patch +Patch6002: Don-t-leak-temporary-file-on-failed-ed-style-patch.patch +Patch6003: Don-t-leak-temporary-file-on-failed-multi-file-ed-st.patch +Patch6004: Fix-swapping-fake-lines-in-pch_swap.patch + +BuildRequires: gcc libselinux-devel libattr-devel ed +Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-root + +%description +Patch takes a patch file containing a difference listing produced by the +diff program and applies those differences to one or more original files, +producing patched versions. + +%package help +Summary: help document +Requires: %{name} = %{version}-%{release} +BuildArch: noarch +%description help +This package provides help document for patch. + +%prep +%autosetup -p1 + +%build +CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE" +%configure --disable-silent-rules +%make_build + +%check +make check + +%install +%makeinstall + +%files +%defattr(-,root,root) +%license COPYING +%{_bindir}/patch + +%files help +%defattr(-,root,root) +%doc NEWS README ChangeLog +%{_mandir}/man1/* + + + +%changelog +* Wed Aug 28 2019 openEuler Buildteam - 2.7.6-6 +- Package Init