1
0
Fork 0
mirror of https://gitlab.alpinelinux.org/alpine/aports.git synced 2025-07-12 18:59:50 +03:00

main/patch: upgrade to 2.8

This commit is contained in:
J0WI 2025-04-06 15:48:23 +02:00 committed by Natanael Copa
parent 7928a60246
commit 094514d20f
10 changed files with 8 additions and 702 deletions

View file

@ -1,33 +0,0 @@
From b5a91a01e5d0897facdd0f49d64b76b0f02b43e1 Mon Sep 17 00:00:00 2001
From: Andreas Gruenbacher <agruen@gnu.org>
Date: Fri, 6 Apr 2018 11:34:51 +0200
Subject: [PATCH] Allow input files to be missing for ed-style patches
* src/pch.c (do_ed_script): Allow input files to be missing so that new
files will be created as with non-ed-style patches.
---
src/pch.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/pch.c b/src/pch.c
index bc6278c..0c5cc26 100644
--- a/src/pch.c
+++ b/src/pch.c
@@ -2394,9 +2394,11 @@ do_ed_script (char const *inname, char const *outname,
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);
+ 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);
--
2.22.0

View file

@ -1,211 +0,0 @@
From 123eaff0d5d1aebe128295959435b9ca5909c26d Mon Sep 17 00:00:00 2001
From: Andreas Gruenbacher <agruen@gnu.org>
Date: Fri, 6 Apr 2018 12:14:49 +0200
Subject: [PATCH] Fix arbitrary command execution in ed-style patches
(CVE-2018-1000156)
* src/pch.c (do_ed_script): Write ed script to a temporary file instead
of piping it to ed: this will cause ed to abort on invalid commands
instead of rejecting them and carrying on.
* tests/ed-style: New test case.
* tests/Makefile.am (TESTS): Add test case.
---
src/pch.c | 91 ++++++++++++++++++++++++++++++++++-------------
tests/Makefile.am | 1 +
tests/ed-style | 41 +++++++++++++++++++++
3 files changed, 108 insertions(+), 25 deletions(-)
create mode 100644 tests/ed-style
diff --git a/src/pch.c b/src/pch.c
index 0c5cc26..4fd5a05 100644
--- a/src/pch.c
+++ b/src/pch.c
@@ -33,6 +33,7 @@
# include <io.h>
#endif
#include <safe.h>
+#include <sys/wait.h>
#define INITHUNKMAX 125 /* initial dynamic allocation size */
@@ -2389,24 +2390,28 @@ do_ed_script (char const *inname, char const *outname,
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;
+ 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;
- 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);
- 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);
@@ -2417,14 +2422,14 @@ do_ed_script (char const *inname, char const *outname,
}
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;
@@ -2437,13 +2442,49 @@ do_ed_script (char const *inname, char const *outname,
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);
+ safe_unlink (tmpname);
if (ofp)
{
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 6b6df63..16f8693 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -32,6 +32,7 @@ TESTS = \
crlf-handling \
dash-o-append \
deep-directories \
+ ed-style \
empty-files \
false-match \
fifo \
diff --git a/tests/ed-style b/tests/ed-style
new file mode 100644
index 0000000..d8c0689
--- /dev/null
+++ b/tests/ed-style
@@ -0,0 +1,41 @@
+# 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 <<EOF
+0a
+foo
+.
+EOF
+
+check 'patch -e foo -i ed1.diff' <<EOF
+EOF
+
+check 'cat foo' <<EOF
+foo
+EOF
+
+cat > ed2.diff <<EOF
+1337a
+r !echo bar
+,p
+EOF
+
+check 'patch -e foo -i ed2.diff 2> /dev/null || echo "Status: $?"' <<EOF
+?
+Status: 2
+EOF
+
+check 'cat foo' <<EOF
+foo
+EOF
--
2.22.0

View file

@ -1,88 +0,0 @@
Patch-Source: https://github.com/mirror/patch/commit/61d7788b83b302207a67b82786f4fd79e3538f30
--
From 61d7788b83b302207a67b82786f4fd79e3538f30 Mon Sep 17 00:00:00 2001
From: Andreas Gruenbacher <agruen@gnu.org>
Date: Thu, 27 Jun 2019 11:10:43 +0200
Subject: [PATCH] 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. */

View file

@ -1,100 +0,0 @@
Patch-Source: https://github.com/archlinux/svntogit-packages/blob/c08d2ec698bc46d4134fc2028d5ac9df1db6e89d/trunk/19599883ffb6a450d2884f081f8ecf68edbed7ee.patch
From 19599883ffb6a450d2884f081f8ecf68edbed7ee Mon Sep 17 00:00:00 2001
From: Jean Delvare <jdelvare@suse.de>
Date: Thu, 3 May 2018 14:31:55 +0200
Subject: [PATCH] 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
@@ -2396,7 +2396,6 @@ do_ed_script (char const *inname, char const *outname,
file_offset beginning_of_this_line;
size_t chars_read;
FILE *tmpfp = 0;
- char const *tmpname;
int tmpfd;
pid_t pid;
@@ -2411,12 +2410,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 (;;) {
@@ -2457,7 +2457,7 @@ do_ed_script (char const *inname, char const *outname,
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 (inerrno != ENOENT)
{
@@ -2484,7 +2484,6 @@ do_ed_script (char const *inname, char const *outname,
pfatal ("Failed to duplicate standard input");
fclose (tmpfp);
- safe_unlink (tmpname);
if (ofp)
{

View file

@ -1,27 +1,15 @@
# Contributor: Sören Tempel <soeren+alpine@soeren-tempel.net>
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
maintainer="Natanael Copa <ncopa@alpinelinux.org>"
pkgname=patch
pkgver=2.7.6
pkgrel=10
pkgver=2.8
pkgrel=0
pkgdesc="Utility to apply diffs to files"
url="https://www.gnu.org/software/patch/patch.html"
arch="all"
license="GPL-3.0-or-later"
makedepends="autoconf automake"
checkdepends="bash ed"
checkdepends="diffutils ed"
subpackages="$pkgname-doc"
source="https://ftp.gnu.org/gnu/patch/patch-$pkgver.tar.xz
0001-Allow-input-files-to-be-missing-for-ed-style-patches.patch
0002-Fix-arbitrary-command-execution-in-ed-style-patches-.patch
0003-memory-allocation.patch
0004-fix-memleak.patch
CVE-2018-6951.patch
CVE-2018-6952.patch
CVE-2019-13636.patch
CVE-2019-13638.patch
CVE-2019-20633.patch
"
builddir="$srcdir"/$pkgname-$pkgver
source="https://ftp.gnu.org/gnu/patch/patch-$pkgver.tar.xz"
# secfixes:
# 2.7.6-r7:
@ -37,13 +25,6 @@ builddir="$srcdir"/$pkgname-$pkgver
# 2.7.6-r4:
# - CVE-2018-6952
prepare() {
default_prepare
update_config_sub
aclocal && autoheader && autoconf && automake --add-missing
}
build() {
gl_cv_func_gettimeofday_clobber=no \
gl_cv_func_tzset_clobber=no \
@ -58,27 +39,13 @@ build() {
}
check() {
make SHELL=bash check
make check
}
package() {
make prefix="$pkgdir"/usr \
mandir="$pkgdir"/usr/share/man \
-C "$builddir" install
rm -f "$pkgdir"/usr/lib/charset.alias
rmdir -p "$pkgdir"/usr/lib 2>/dev/null || true
make DESTDIR="$pkgdir" install
}
sha512sums="
fcca87bdb67a88685a8a25597f9e015f5e60197b9a269fa350ae35a7991ed8da553939b4bbc7f7d3cfd863c67142af403b04165633acbce4339056a905e87fbd patch-2.7.6.tar.xz
33e8a82f5ee6b896fd434e7de1ca9e16e8d317941a021bea8c53afd5bf210774e8727df22f8d8f63f255de10de5a26428047bc710b033423d1e7a459cbbaf83a 0001-Allow-input-files-to-be-missing-for-ed-style-patches.patch
d0d46e28c5fdcd5fe16826cbcf39d5a74fdf2593375d5206aa7bad759f16dbebeca3bf259239f99c13344579044a3de1000d705065cc19e917266bca6e5c0630 0002-Fix-arbitrary-command-execution-in-ed-style-patches-.patch
3dd30ef35da27f83678fe61ae132de0e9f7c3262831ada5decbe8ac970bf928d7fad9c99f58484f90898b15ce11f297cd078588c29f8528e582842a9bd66d74f 0003-memory-allocation.patch
94a8dc8eddd814f0837a8cb673f09d8a6cd12072b46466d94e01d8273ef7499a9d0568f5cae53ef80983b36cb00de272ae8054a7a5755c043bc01c1bafdc96a2 0004-fix-memleak.patch
db51d0b791d38dd4f1b373621ee18620ae339b172f58a79420fdaa4a4b1b1d9df239cf61bbddc4e6a4896b28b8cffc7c99161eb5e2facaec8df86a1bf7755bc0 CVE-2018-6951.patch
5d2eaef629bae92e5b4e5e57d140c24a73e2811306d5f2854858f846646b034d2da315071f478bcf6f8d856a065b9bb073f76322e8e3a42616bc212281ce6945 CVE-2018-6952.patch
029b92bb899d0b1165cfe7f55b5a4c2d7090852f52e5c85a6bb1cf5913c914a5c68c6c34517e84f0a020a56d21814f8c18b934c8ebe059ba4eddece78a3a258c CVE-2019-13636.patch
d60f8c2364fca9b73aa73b5914cfd6571d11528d13fa7703ccfa93730cbdf8a6e4c9ca04cb7d02a40d33c38075890790b490052d5217e728b0948991da937980 CVE-2019-13638.patch
e988836c90946282e70fca0fe29a52405a357b14bfdc8fce3afb680d7d1b25c4bf9d9cbc5612e3bb2d9379192635d7f1bf1b7b16c23b13d77450ec87dc5e3fe4 CVE-2019-20633.patch
d689d696660a662753e8660792733c3be0a94c76abfe7a28b0f9f70300c3a42d6437d081553a59bfde6e1b0d5ee13ed89be48d0b00b6da2cadbfc14a15ada603 patch-2.8.tar.xz
"

View file

@ -1,29 +0,0 @@
From f290f48a621867084884bfff87f8093c15195e6a Mon Sep 17 00:00:00 2001
From: Andreas Gruenbacher <agruen@gnu.org>
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

View file

@ -1,27 +0,0 @@
From 9c986353e420ead6e706262bf204d6e03322c300 Mon Sep 17 00:00:00 2001
From: Andreas Gruenbacher <agruen@gnu.org>
Date: Fri, 17 Aug 2018 13:35:40 +0200
Subject: [PATCH] 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;

View file

@ -1,109 +0,0 @@
From dce4683cbbe107a95f1f0d45fabc304acfb5d71a Mon Sep 17 00:00:00 2001
From: Andreas Gruenbacher <agruen@gnu.org>
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
@@ -388,7 +388,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));
@@ -579,10 +579,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)
{
@@ -625,6 +628,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);
@@ -640,9 +645,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

View file

@ -1,38 +0,0 @@
From 3fcd042d26d70856e826a42b5f93dc4854d80bf0 Mon Sep 17 00:00:00 2001
From: Andreas Gruenbacher <agruen@gnu.org>
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

View file

@ -1,26 +0,0 @@
From 15b158db3ae11cb835f2eb8d2eb48e09d1a4af48 Mon Sep 17 00:00:00 2001
From: Andreas Gruenbacher <agruen@gnu.org>
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.2.1