Accepting request 976181 from devel:tools

- fix-swapping-fake-lines-in-pch_swap.patch: Fix swapping fake
  lines in pch_swap. This bug was causing a double free leading to
  a crash (boo#1080985 CVE-2018-6952).
- abort-when-cleaning-up-fails.patch: Abort when cleaning up fails.
  This bug could cause an infinite loop when a patch wouldn't
  apply, leading to a segmentation fault (boo#1111572).
- dont-follow-symlinks-unless-asked.patch: Don't follow symlinks
  unless --follow-symlinks is given. This increases the security
  against malicious patches (boo#1142041 CVE-2019-13636).
- pass-the-correct-stat-to-backup-files.patch: Pass the correct
  stat to backup files. This bug would occasionally cause backup
  files to be missing when all hunks failed to apply (boo#1198106).

OBS-URL: https://build.opensuse.org/request/show/976181
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/patch?expand=0&rev=45
This commit is contained in:
Dominique Leuenberger 2022-05-12 20:57:23 +00:00 committed by Git OBS Bridge
commit 0ae34683d5
6 changed files with 262 additions and 1 deletions

View File

@ -0,0 +1,48 @@
From: Andreas Gruenbacher <agruen@gnu.org>
Date: Fri, 28 Jun 2019 00:30:25 +0200
Subject: Abort when cleaning up fails
Patch-mainline: Yes
Git-commit: b7b028a77bd855f6f56b17c8837fc1cca77b469d
References: boo#1111572 savannah#54845
When a fatal error triggers during cleanup, another attempt will be made to
clean up, which will likely lead to the same fatal error. So instead, bail out
when that happens.
src/patch.c (cleanup): Bail out when called recursively.
(main): There is no need to call output_files() before cleanup() as cleanup()
already does that.
---
src/patch.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--- a/src/patch.c
+++ b/src/patch.c
@@ -681,7 +681,6 @@ main (int argc, char **argv)
}
if (outstate.ofp && (ferror (outstate.ofp) || fclose (outstate.ofp) != 0))
write_fatal ();
- output_files (NULL);
cleanup ();
delete_files ();
if (somefailed)
@@ -1977,7 +1976,6 @@ void
fatal_exit (int sig)
{
cleanup ();
-
if (sig)
exit_with_signal (sig);
@@ -1997,6 +1995,12 @@ remove_if_needed (char const *name, bool
static void
cleanup (void)
{
+ static bool already_cleaning_up;
+
+ if (already_cleaning_up)
+ return;
+ already_cleaning_up = true;
+
remove_if_needed (TMPINNAME, &TMPINNAME_needs_removal);
remove_if_needed (TMPOUTNAME, &TMPOUTNAME_needs_removal);
remove_if_needed (TMPPATNAME, &TMPPATNAME_needs_removal);

View File

@ -0,0 +1,103 @@
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
Patch-mainline: Yes
Git-commit: dce4683cbbe107a95f1f0d45fabc304acfb5d71a
References: boo#1142041 CVE-2019-13636
* 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(-)
--- 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)
--- a/src/util.c
+++ b/src/util.c
@@ -388,7 +388,7 @@ create_backup (char const *to, const str
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_
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
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
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)

View File

@ -0,0 +1,27 @@
From: Andreas Gruenbacher <agruen@gnu.org>
Date: Fri, 17 Aug 2018 13:35:40 +0200
Subject: Fix swapping fake lines in pch_swap
Patch-mainline: Yes
Git-commit: 9c986353e420ead6e706262bf204d6e03322c300
References: boo#1080985 savannah#53133 CVE-2018-6952
* 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(-)
--- a/src/pch.c
+++ b/src/pch.c
@@ -2115,7 +2115,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

@ -0,0 +1,59 @@
From: Takashi Iwai <tiwai@suse.de>
Date: Wed, 6 Apr 2022 10:48:35 +0200
Subject: Pass the correct stat to backup files
Patch-mainline: Yes
Git-commit: c835ecc67b7e37c0d0b7dd7e032209fdaa285808
References: boo#1198106 savananh#62364
The last case to call output_file() in the main loop is
output_file (outname, NULL, &tmpoutst, NULL, NULL,
file_type | 0, backup);
and this essentially means to create a backup file (where to=NULL)
only if backup=true, and does nothing else.
And, in the current code, the passed file stat (&tmpoutst) is a file
stat of the temporary file that has been processed, not the original
file (outname) to be backed up. When the backup is performed
immediately, this is no big problem. However, output_file() may
schedule the deferred handling, and the given file may be backed up at
a later point. The problem is that create_backup() tries to avoid the
backup of the same file twice, and it checks the given stat i-node
number in the hash list. Since it's a stat of a temporary file, the
same i-node number may be reused once a temp file is deleted and
another is created. This results in a false-positive detection of the
already existing file, eventually missing a backup file.
This patch attempts to address the issue:
- Modify the condition for better understanding, clearly indicating
that the code there is for creating a backup file
- Pass the stat of the original file instead of a temporary file
BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1198106
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jean Delvare <jdelvare@suse.de>
---
src/patch.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
--- a/src/patch.c
+++ b/src/patch.c
@@ -611,9 +611,16 @@ main (int argc, char **argv)
output_file (NULL, NULL, NULL, inname, &instat,
mode, backup);
}
- else
- output_file (outname, NULL, &tmpoutst, NULL, NULL,
- file_type | 0, backup);
+ else if (backup)
+ {
+ struct stat outstat;
+
+ if (stat_file (outname, &outstat) != 0)
+ say ("Cannot stat file %s, skipping backup\n", outname);
+ else
+ output_file (outname, NULL, &outstat, NULL, NULL,
+ file_type | 0, true);
+ }
}
}
}

View File

@ -1,3 +1,19 @@
-------------------------------------------------------------------
Tue May 10 16:41:54 UTC 2022 - Jean Delvare <jdelvare@suse.de>
- fix-swapping-fake-lines-in-pch_swap.patch: Fix swapping fake
lines in pch_swap. This bug was causing a double free leading to
a crash (boo#1080985 CVE-2018-6952).
- abort-when-cleaning-up-fails.patch: Abort when cleaning up fails.
This bug could cause an infinite loop when a patch wouldn't
apply, leading to a segmentation fault (boo#1111572).
- dont-follow-symlinks-unless-asked.patch: Don't follow symlinks
unless --follow-symlinks is given. This increases the security
against malicious patches (boo#1142041 CVE-2019-13636).
- pass-the-correct-stat-to-backup-files.patch: Pass the correct
stat to backup files. This bug would occasionally cause backup
files to be missing when all hunks failed to apply (boo#1198106).
-------------------------------------------------------------------
Wed Sep 29 10:33:36 UTC 2021 - Dominique Leuenberger <dimstar@opensuse.org>

View File

@ -1,7 +1,7 @@
#
# spec file for package patch
#
# Copyright (c) 2021 SUSE LLC
# Copyright (c) 2022 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -35,6 +35,10 @@ Patch6: ed-style-05-minor-cleanups.patch
Patch7: ed-style-06-fix-test-failure.patch
Patch8: ed-style-07-dont-leak-tmp-file.patch
Patch9: ed-style-08-dont-leak-tmp-file-multi.patch
Patch10: fix-swapping-fake-lines-in-pch_swap.patch
Patch11: abort-when-cleaning-up-fails.patch
Patch12: dont-follow-symlinks-unless-asked.patch
Patch13: pass-the-correct-stat-to-backup-files.patch
# See bnc#662957. The fix for CVE-2010-4651 breaks the way interdiff was
# invoking patch, so interdiff had to be fixed too.
Conflicts: patchutils < 0.3.2
@ -58,6 +62,10 @@ changed files (generated by the diff command) to the original files.
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%build
export CFLAGS="%{optflags} -Wall -O2 -pipe"