From b4e5bfd9d4c04c2f942bbecce62e4394d827de16 Mon Sep 17 00:00:00 2001 From: Thomas Deutschmann Date: Fri, 16 Aug 2019 14:38:46 +0200 Subject: sys-devel/patch: rev bump to add some patches Bug: https://bugs.gentoo.org/690136 Package-Manager: Portage-2.3.71, Repoman-2.3.17 Signed-off-by: Thomas Deutschmann --- ...lid-memory-access-in-context-format-diffs.patch | 26 +++++ .../files/patch-2.7.6-CVE-2018-1000156-fix1.patch | 102 +++++++++++++++++++ .../files/patch-2.7.6-CVE-2018-1000156-fix2.patch | 37 +++++++ .../patch/files/patch-2.7.6-CVE-2019-13636.patch | 108 +++++++++++++++++++++ .../patch/files/patch-2.7.6-CVE-2019-13638.patch | 38 ++++++++ ...hen-RLIMIT_NOFILE-is-set-to-RLIM_INFINITY.patch | 89 +++++++++++++++++ sys-devel/patch/patch-2.7.6-r4.ebuild | 46 +++++++++ 7 files changed, 446 insertions(+) create mode 100644 sys-devel/patch/files/patch-2.7.6-Avoid-invalid-memory-access-in-context-format-diffs.patch create mode 100644 sys-devel/patch/files/patch-2.7.6-CVE-2018-1000156-fix1.patch create mode 100644 sys-devel/patch/files/patch-2.7.6-CVE-2018-1000156-fix2.patch create mode 100644 sys-devel/patch/files/patch-2.7.6-CVE-2019-13636.patch create mode 100644 sys-devel/patch/files/patch-2.7.6-CVE-2019-13638.patch create mode 100644 sys-devel/patch/files/patch-2.7.6-Do-not-crash-when-RLIMIT_NOFILE-is-set-to-RLIM_INFINITY.patch create mode 100644 sys-devel/patch/patch-2.7.6-r4.ebuild (limited to 'sys-devel/patch') diff --git a/sys-devel/patch/files/patch-2.7.6-Avoid-invalid-memory-access-in-context-format-diffs.patch b/sys-devel/patch/files/patch-2.7.6-Avoid-invalid-memory-access-in-context-format-diffs.patch new file mode 100644 index 000000000000..5eef875b85d4 --- /dev/null +++ b/sys-devel/patch/files/patch-2.7.6-Avoid-invalid-memory-access-in-context-format-diffs.patch @@ -0,0 +1,26 @@ +From 15b158db3ae11cb835f2eb8d2eb48e09d1a4af48 Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Mon, 15 Jul 2019 19:10:02 +0200 +Subject: Avoid invalid memory access in context format diffs + +* src/pch.c (another_hunk): Avoid invalid memory access in context format +diffs. +--- + src/pch.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/pch.c b/src/pch.c +index a500ad9..cb54e03 100644 +--- a/src/pch.c ++++ b/src/pch.c +@@ -1328,6 +1328,7 @@ another_hunk (enum diff difftype, bool rev) + ptrn_prefix_context = context; + ptrn_suffix_context = context; + if (repl_beginning ++ || p_end <= 0 + || (p_end + != p_ptrn_lines + 1 + (p_Char[p_end - 1] == '\n'))) + { +-- +cgit v1.0-41-gc330 + diff --git a/sys-devel/patch/files/patch-2.7.6-CVE-2018-1000156-fix1.patch b/sys-devel/patch/files/patch-2.7.6-CVE-2018-1000156-fix1.patch new file mode 100644 index 000000000000..d2492f593175 --- /dev/null +++ b/sys-devel/patch/files/patch-2.7.6-CVE-2018-1000156-fix1.patch @@ -0,0 +1,102 @@ +From 19599883ffb6a450d2884f081f8ecf68edbed7ee Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Thu, 3 May 2018 14:31:55 +0200 +Subject: 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 +@@ -2003,6 +2003,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 +@@ -2392,7 +2392,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; + pid_t pid; + +@@ -2404,12 +2403,13 @@ do_ed_script (char const *inname, char const *outname, + 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 (;;) { +@@ -2449,7 +2449,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; +@@ -2482,7 +2482,6 @@ do_ed_script (char const *inname, char c + } + + fclose (tmpfp); +- safe_unlink (tmpname); + + if (ofp) + { +-- +cgit v1.0-41-gc330 + diff --git a/sys-devel/patch/files/patch-2.7.6-CVE-2018-1000156-fix2.patch b/sys-devel/patch/files/patch-2.7.6-CVE-2018-1000156-fix2.patch new file mode 100644 index 000000000000..7b74ff06c4bd --- /dev/null +++ b/sys-devel/patch/files/patch-2.7.6-CVE-2018-1000156-fix2.patch @@ -0,0 +1,37 @@ +From 369dcccdfa6336e5a873d6d63705cfbe04c55727 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Mon, 7 May 2018 15:14:45 +0200 +Subject: 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 + + 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) + { +-- +cgit v1.0-41-gc330 + diff --git a/sys-devel/patch/files/patch-2.7.6-CVE-2019-13636.patch b/sys-devel/patch/files/patch-2.7.6-CVE-2019-13636.patch new file mode 100644 index 000000000000..3515399f073d --- /dev/null +++ b/sys-devel/patch/files/patch-2.7.6-CVE-2019-13636.patch @@ -0,0 +1,108 @@ +From dce4683cbbe107a95f1f0d45fabc304acfb5d71a Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Mon, 15 Jul 2019 16:21:48 +0200 +Subject: Don't follow symlinks unless --follow-symlinks is given + +* src/inp.c (plan_a, plan_b), src/util.c (copy_to_fd, copy_file, +append_to_file): Unless the --follow-symlinks option is given, open files with +the O_NOFOLLOW flag to avoid following symlinks. So far, we were only doing +that consistently for input files. +* src/util.c (create_backup): When creating empty backup files, (re)create them +with O_CREAT | O_EXCL to avoid following symlinks in that case as well. +--- + src/inp.c | 12 ++++++++++-- + src/util.c | 14 +++++++++++--- + 2 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/src/inp.c b/src/inp.c +index 32d0919..22d7473 100644 +--- a/src/inp.c ++++ b/src/inp.c +@@ -238,8 +238,13 @@ plan_a (char const *filename) + { + if (S_ISREG (instat.st_mode)) + { +- int ifd = safe_open (filename, O_RDONLY|binary_transput, 0); ++ int flags = O_RDONLY | binary_transput; + size_t buffered = 0, n; ++ int ifd; ++ ++ if (! follow_symlinks) ++ flags |= O_NOFOLLOW; ++ ifd = safe_open (filename, flags, 0); + if (ifd < 0) + pfatal ("can't open file %s", quotearg (filename)); + +@@ -340,6 +345,7 @@ plan_a (char const *filename) + static void + plan_b (char const *filename) + { ++ int flags = O_RDONLY | binary_transput; + int ifd; + FILE *ifp; + int c; +@@ -353,7 +359,9 @@ plan_b (char const *filename) + + if (instat.st_size == 0) + filename = NULL_DEVICE; +- if ((ifd = safe_open (filename, O_RDONLY | binary_transput, 0)) < 0 ++ if (! follow_symlinks) ++ flags |= O_NOFOLLOW; ++ if ((ifd = safe_open (filename, flags, 0)) < 0 + || ! (ifp = fdopen (ifd, binary_transput ? "rb" : "r"))) + pfatal ("Can't open file %s", quotearg (filename)); + if (TMPINNAME_needs_removal) +diff --git a/src/util.c b/src/util.c +index 1cc08ba..fb38307 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -393,7 +393,7 @@ create_backup (char const *to, const struct stat *to_st, bool leave_original) + + try_makedirs_errno = ENOENT; + safe_unlink (bakname); +- while ((fd = safe_open (bakname, O_CREAT | O_WRONLY | O_TRUNC, 0666)) < 0) ++ while ((fd = safe_open (bakname, O_CREAT | O_EXCL | O_WRONLY | O_TRUNC, 0666)) < 0) + { + if (errno != try_makedirs_errno) + pfatal ("Can't create file %s", quotearg (bakname)); +@@ -584,10 +584,13 @@ create_file (char const *file, int open_flags, mode_t mode, + static void + copy_to_fd (const char *from, int tofd) + { ++ int from_flags = O_RDONLY | O_BINARY; + int fromfd; + ssize_t i; + +- if ((fromfd = safe_open (from, O_RDONLY | O_BINARY, 0)) < 0) ++ if (! follow_symlinks) ++ from_flags |= O_NOFOLLOW; ++ if ((fromfd = safe_open (from, from_flags, 0)) < 0) + pfatal ("Can't reopen file %s", quotearg (from)); + while ((i = read (fromfd, buf, bufsize)) != 0) + { +@@ -630,6 +633,8 @@ copy_file (char const *from, char const *to, struct stat *tost, + else + { + assert (S_ISREG (mode)); ++ if (! follow_symlinks) ++ to_flags |= O_NOFOLLOW; + tofd = create_file (to, O_WRONLY | O_BINARY | to_flags, mode, + to_dir_known_to_exist); + copy_to_fd (from, tofd); +@@ -645,9 +650,12 @@ copy_file (char const *from, char const *to, struct stat *tost, + void + append_to_file (char const *from, char const *to) + { ++ int to_flags = O_WRONLY | O_APPEND | O_BINARY; + int tofd; + +- if ((tofd = safe_open (to, O_WRONLY | O_BINARY | O_APPEND, 0)) < 0) ++ if (! follow_symlinks) ++ to_flags |= O_NOFOLLOW; ++ if ((tofd = safe_open (to, to_flags, 0)) < 0) + pfatal ("Can't reopen file %s", quotearg (to)); + copy_to_fd (from, tofd); + if (close (tofd) != 0) +-- +cgit v1.0-41-gc330 + diff --git a/sys-devel/patch/files/patch-2.7.6-CVE-2019-13638.patch b/sys-devel/patch/files/patch-2.7.6-CVE-2019-13638.patch new file mode 100644 index 000000000000..38caff628aaf --- /dev/null +++ b/sys-devel/patch/files/patch-2.7.6-CVE-2019-13638.patch @@ -0,0 +1,38 @@ +From 3fcd042d26d70856e826a42b5f93dc4854d80bf0 Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Fri, 6 Apr 2018 19:36:15 +0200 +Subject: Invoke ed directly instead of using the shell + +* src/pch.c (do_ed_script): Invoke ed directly instead of using a shell +command to avoid quoting vulnerabilities. +--- + src/pch.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/src/pch.c b/src/pch.c +index 4fd5a05..16e001a 100644 +--- a/src/pch.c ++++ b/src/pch.c +@@ -2459,9 +2459,6 @@ do_ed_script (char const *inname, char const *outname, + *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(); +@@ -2470,7 +2467,8 @@ do_ed_script (char const *inname, char const *outname, + else if (pid == 0) + { + dup2 (tmpfd, 0); +- execl ("/bin/sh", "sh", "-c", buf, (char *) 0); ++ assert (outname[0] != '!' && outname[0] != '-'); ++ execlp (editor_program, editor_program, "-", outname, (char *) NULL); + _exit (2); + } + else +-- +cgit v1.0-41-gc330 + diff --git a/sys-devel/patch/files/patch-2.7.6-Do-not-crash-when-RLIMIT_NOFILE-is-set-to-RLIM_INFINITY.patch b/sys-devel/patch/files/patch-2.7.6-Do-not-crash-when-RLIMIT_NOFILE-is-set-to-RLIM_INFINITY.patch new file mode 100644 index 000000000000..961e57861382 --- /dev/null +++ b/sys-devel/patch/files/patch-2.7.6-Do-not-crash-when-RLIMIT_NOFILE-is-set-to-RLIM_INFINITY.patch @@ -0,0 +1,89 @@ +From 61d7788b83b302207a67b82786f4fd79e3538f30 Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Thu, 27 Jun 2019 11:10:43 +0200 +Subject: Don't crash when RLIMIT_NOFILE is set to RLIM_INFINITY + +* src/safe.c (min_cached_fds): Define minimum number of cached dir file +descriptors. +(max_cached_fds): Change type to rlim_t to allow storing RLIM_INFINITY. +(init_dirfd_cache): Set max_cached_fds to RLIM_INFINITY when RLIMIT_NOFILE is +RLIM_INFINITY. Set the initial hash table size to min_cached_fds, independent +of RLIMIT_NOFILE: patches commonly only affect one or a few files, so a small +hash table will usually suffice; if needed, the hash table will grow. +(insert_cached_dirfd): Don't shrink the cache when max_cached_fds is +RLIM_INFINITY. +--- + src/safe.c | 36 +++++++++++++++++++++++------------- + 1 file changed, 23 insertions(+), 13 deletions(-) + +diff --git a/src/safe.c b/src/safe.c +index 5a7202f..f147b0e 100644 +--- a/src/safe.c ++++ b/src/safe.c +@@ -67,7 +67,8 @@ struct cached_dirfd { + }; + + static Hash_table *cached_dirfds = NULL; +-static size_t max_cached_fds; ++static rlim_t min_cached_fds = 8; ++static rlim_t max_cached_fds; + LIST_HEAD (lru_list); + + static size_t hash_cached_dirfd (const void *entry, size_t table_size) +@@ -98,11 +99,17 @@ static void init_dirfd_cache (void) + { + struct rlimit nofile; + +- max_cached_fds = 8; + if (getrlimit (RLIMIT_NOFILE, &nofile) == 0) +- max_cached_fds = MAX (nofile.rlim_cur / 4, max_cached_fds); ++ { ++ if (nofile.rlim_cur == RLIM_INFINITY) ++ max_cached_fds = RLIM_INFINITY; ++ else ++ max_cached_fds = MAX (nofile.rlim_cur / 4, min_cached_fds); ++ } ++ else ++ max_cached_fds = min_cached_fds; + +- cached_dirfds = hash_initialize (max_cached_fds, ++ cached_dirfds = hash_initialize (min_cached_fds, + NULL, + hash_cached_dirfd, + compare_cached_dirfds, +@@ -148,20 +155,23 @@ static void insert_cached_dirfd (struct cached_dirfd *entry, int keepfd) + if (cached_dirfds == NULL) + init_dirfd_cache (); + +- /* Trim off the least recently used entries */ +- while (hash_get_n_entries (cached_dirfds) >= max_cached_fds) ++ if (max_cached_fds != RLIM_INFINITY) + { +- struct cached_dirfd *last = +- list_entry (lru_list.prev, struct cached_dirfd, lru_link); +- if (&last->lru_link == &lru_list) +- break; +- if (last->fd == keepfd) ++ /* Trim off the least recently used entries */ ++ while (hash_get_n_entries (cached_dirfds) >= max_cached_fds) + { +- last = list_entry (last->lru_link.prev, struct cached_dirfd, lru_link); ++ struct cached_dirfd *last = ++ list_entry (lru_list.prev, struct cached_dirfd, lru_link); + if (&last->lru_link == &lru_list) + break; ++ if (last->fd == keepfd) ++ { ++ last = list_entry (last->lru_link.prev, struct cached_dirfd, lru_link); ++ if (&last->lru_link == &lru_list) ++ break; ++ } ++ remove_cached_dirfd (last); + } +- remove_cached_dirfd (last); + } + + /* Only insert if the parent still exists. */ +-- +cgit v1.0-41-gc330 + diff --git a/sys-devel/patch/patch-2.7.6-r4.ebuild b/sys-devel/patch/patch-2.7.6-r4.ebuild new file mode 100644 index 000000000000..cce90dd296d7 --- /dev/null +++ b/sys-devel/patch/patch-2.7.6-r4.ebuild @@ -0,0 +1,46 @@ +# Copyright 1999-2019 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI="7" + +inherit flag-o-matic + +DESCRIPTION="Utility to apply diffs to files" +HOMEPAGE="https://www.gnu.org/software/patch/patch.html" +SRC_URI="mirror://gnu/patch/${P}.tar.xz" + +LICENSE="GPL-3+" +SLOT="0" +KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sh ~sparc ~x86 ~ppc-aix ~x64-cygwin ~amd64-fbsd ~x86-fbsd ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~m68k-mint ~sparc-solaris ~sparc64-solaris ~x64-solaris ~x86-solaris" +IUSE="static test xattr" + +RDEPEND="xattr? ( sys-apps/attr )" +DEPEND="${RDEPEND} + test? ( sys-apps/ed )" + +PATCHES=( + "${FILESDIR}"/${P}-fix-test-suite.patch + "${FILESDIR}"/${PN}-2.7.6-fix-error-handling-with-git-style-patches.patch + "${FILESDIR}"/${PN}-2.7.6-CVE-2018-6951.patch + "${FILESDIR}"/${PN}-2.7.6-allow-input-files-to-be-missing-for-ed-style-patches.patch + "${FILESDIR}"/${PN}-2.7.6-CVE-2018-1000156.patch + "${FILESDIR}"/${PN}-2.7.6-CVE-2018-6952.patch + "${FILESDIR}"/${PN}-2.7.6-Do-not-crash-when-RLIMIT_NOFILE-is-set-to-RLIM_INFINITY.patch + "${FILESDIR}"/${PN}-2.7.6-CVE-2018-1000156-fix1.patch + "${FILESDIR}"/${PN}-2.7.6-CVE-2018-1000156-fix2.patch + "${FILESDIR}"/${PN}-2.7.6-CVE-2019-13636.patch + "${FILESDIR}"/${PN}-2.7.6-CVE-2019-13638.patch + "${FILESDIR}"/${PN}-2.7.6-Avoid-invalid-memory-access-in-context-format-diffs.patch +) + +src_configure() { + use static && append-ldflags -static + + local myeconfargs=( + $(use_enable xattr) + --program-prefix="$(use userland_BSD && echo g)" + ) + # Do not let $ED mess up the search for `ed` 470210. + ac_cv_path_ED=$(type -P ed) \ + econf "${myeconfargs[@]}" +} -- cgit v1.2.3-18-g5258