[patch/f21] Include ae88d1c270df6ba685bd422f3bf2607367de7cfc from upstream.
Tim Waugh
twaugh at fedoraproject.org
Tue Jan 20 13:44:01 UTC 2015
commit 08856568121e23fdeb2ef1499bb12152cadc39bb
Author: Tim Waugh <twaugh at redhat.com>
Date: Tue Jan 20 13:20:02 2015 +0000
Include ae88d1c270df6ba685bd422f3bf2607367de7cfc from upstream.
patch-CVE-2010-4651.patch | 164 ---------------------------------------------
patch-CVE-2015-1196.patch | 106 ++++++++++++++++++++++-------
patch-selinux.patch | 49 +++++++------
patch.spec | 4 +-
4 files changed, 109 insertions(+), 214 deletions(-)
---
diff --git a/patch-CVE-2015-1196.patch b/patch-CVE-2015-1196.patch
index 899ee01..374dc3d 100644
--- a/patch-CVE-2015-1196.patch
+++ b/patch-CVE-2015-1196.patch
@@ -1,12 +1,44 @@
-diff -up patch-2.7.1/NEWS.CVE-2015-1196 patch-2.7.1/NEWS
diff -up patch-2.7.1/src/pch.c.CVE-2015-1196 patch-2.7.1/src/pch.c
---- patch-2.7.1/src/pch.c.CVE-2015-1196 2015-01-20 12:23:34.808516117 +0000
-+++ patch-2.7.1/src/pch.c 2015-01-20 12:24:15.763652714 +0000
-@@ -454,6 +454,60 @@ name_is_valid (char const *name)
- return is_valid;
+--- patch-2.7.1/src/pch.c.CVE-2015-1196 2012-09-22 18:44:33.000000000 +0100
++++ patch-2.7.1/src/pch.c 2015-01-20 13:29:14.304859557 +0000
+@@ -387,29 +387,6 @@ skip_hex_digits (char const *str)
+ return s == str ? NULL : s;
}
-+bool
+-/* Check if we are in the root of a particular filesystem namespace ("/" on
+- UNIX or a particular drive's root on DOS-like systems). */
+-static bool
+-cwd_is_root (char const *name)
+-{
+- unsigned int prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
+- char root[prefix_len + 2];
+- struct stat st;
+- dev_t root_dev;
+- ino_t root_ino;
+-
+- memcpy (root, name, prefix_len);
+- root[prefix_len] = '/';
+- root[prefix_len + 1] = 0;
+- if (stat (root, &st))
+- return false;
+- root_dev = st.st_dev;
+- root_ino = st.st_ino;
+- if (stat (".", &st))
+- return false;
+- return root_dev == st.st_dev && root_ino == st.st_ino;
+-}
+-
+ static bool
+ name_is_valid (char const *name)
+ {
+diff -up patch-2.7.1/src/util.c.CVE-2015-1196 patch-2.7.1/src/util.c
+--- patch-2.7.1/src/util.c.CVE-2015-1196 2012-09-22 21:09:10.000000000 +0100
++++ patch-2.7.1/src/util.c 2015-01-20 13:29:14.305859561 +0000
+@@ -422,6 +422,60 @@ create_backup (char const *to, const str
+ }
+ }
+
++static bool
+symlink_target_is_valid (char const *target, char const *to)
+{
+ bool is_valid;
@@ -60,24 +92,10 @@ diff -up patch-2.7.1/src/pch.c.CVE-2015-1196 patch-2.7.1/src/pch.c
+ return is_valid || cwd_is_root (to);
+}
+
- /* Determine what kind of diff is in the remaining part of the patch file. */
-
- static enum diff
-diff -up patch-2.7.1/src/pch.h.CVE-2015-1196 patch-2.7.1/src/pch.h
---- patch-2.7.1/src/pch.h.CVE-2015-1196 2012-09-22 18:37:21.000000000 +0100
-+++ patch-2.7.1/src/pch.h 2015-01-20 12:24:15.763652714 +0000
-@@ -37,6 +37,7 @@ bool pch_write_line (lin, FILE *);
- bool there_is_another_patch (bool, mode_t *);
- char *pfetch (lin) _GL_ATTRIBUTE_PURE;
- char pch_char (lin) _GL_ATTRIBUTE_PURE;
-+bool symlink_target_is_valid (char const *, char const *);
- int another_hunk (enum diff, bool);
- int pch_says_nonexistent (bool) _GL_ATTRIBUTE_PURE;
- size_t pch_line_len (lin) _GL_ATTRIBUTE_PURE;
-diff -up patch-2.7.1/src/util.c.CVE-2015-1196 patch-2.7.1/src/util.c
---- patch-2.7.1/src/util.c.CVE-2015-1196 2015-01-20 12:23:34.808516117 +0000
-+++ patch-2.7.1/src/util.c 2015-01-20 12:24:15.764652717 +0000
-@@ -478,6 +478,13 @@ move_file (char const *from, bool *from_
+ /* Move a file FROM (where *FROM_NEEDS_REMOVAL is nonzero if FROM
+ needs removal when cleaning up at the end of execution, and where
+ *FROMST is FROM's status if known),
+@@ -465,6 +519,13 @@ move_file (char const *from, bool *from_
read_fatal ();
buffer[size] = 0;
@@ -91,9 +109,47 @@ diff -up patch-2.7.1/src/util.c.CVE-2015-1196 patch-2.7.1/src/util.c
if (! backup)
{
if (unlink (to) == 0)
+@@ -1660,3 +1721,26 @@ int stat_file (char const *filename, str
+
+ return xstat (filename, st) == 0 ? 0 : errno;
+ }
++
++/* Check if we are in the root of a particular filesystem namespace ("/" on
++ UNIX or a particular drive's root on DOS-like systems). */
++bool
++cwd_is_root (char const *name)
++{
++ unsigned int prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
++ char root[prefix_len + 2];
++ struct stat st;
++ dev_t root_dev;
++ ino_t root_ino;
++
++ memcpy (root, name, prefix_len);
++ root[prefix_len] = '/';
++ root[prefix_len + 1] = 0;
++ if (stat (root, &st))
++ return false;
++ root_dev = st.st_dev;
++ root_ino = st.st_ino;
++ if (stat (".", &st))
++ return false;
++ return root_dev == st.st_dev && root_ino == st.st_ino;
++}
+diff -up patch-2.7.1/src/util.h.CVE-2015-1196 patch-2.7.1/src/util.h
+--- patch-2.7.1/src/util.h.CVE-2015-1196 2012-09-21 21:21:16.000000000 +0100
++++ patch-2.7.1/src/util.h 2015-01-20 13:29:14.306859564 +0000
+@@ -69,6 +69,7 @@ enum file_id_type lookup_file_id (struct
+ void set_queued_output (struct stat const *, bool);
+ bool has_queued_output (struct stat const *);
+ int stat_file (char const *, struct stat *);
++bool cwd_is_root (char const *);
+
+ enum file_attributes {
+ FA_TIMES = 1,
diff -up patch-2.7.1/tests/symlinks.CVE-2015-1196 patch-2.7.1/tests/symlinks
--- patch-2.7.1/tests/symlinks.CVE-2015-1196 2012-09-19 02:18:42.000000000 +0100
-+++ patch-2.7.1/tests/symlinks 2015-01-20 12:24:15.764652717 +0000
++++ patch-2.7.1/tests/symlinks 2015-01-20 13:29:14.306859564 +0000
@@ -146,6 +146,59 @@ ncheck 'test ! -L symlink'
# --------------------------------------------------------------
diff --git a/patch-selinux.patch b/patch-selinux.patch
index 5fcde18..941ff29 100644
--- a/patch-selinux.patch
+++ b/patch-selinux.patch
@@ -1,6 +1,6 @@
diff -up patch-2.7.1/src/common.h.selinux patch-2.7.1/src/common.h
--- patch-2.7.1/src/common.h.selinux 2012-09-28 15:00:04.000000000 +0100
-+++ patch-2.7.1/src/common.h 2015-01-20 12:26:32.914110148 +0000
++++ patch-2.7.1/src/common.h 2015-01-20 13:29:30.388915881 +0000
@@ -30,6 +30,8 @@
#include <sys/types.h>
#include <time.h>
@@ -20,7 +20,7 @@ diff -up patch-2.7.1/src/common.h.selinux patch-2.7.1/src/common.h
diff -up patch-2.7.1/src/inp.c.selinux patch-2.7.1/src/inp.c
--- patch-2.7.1/src/inp.c.selinux 2012-09-19 02:07:31.000000000 +0100
-+++ patch-2.7.1/src/inp.c 2015-01-20 12:26:32.914110148 +0000
++++ patch-2.7.1/src/inp.c 2015-01-20 13:29:30.388915881 +0000
@@ -138,7 +138,7 @@ get_input_file (char const *filename, ch
char *getbuf;
@@ -49,7 +49,7 @@ diff -up patch-2.7.1/src/inp.c.selinux patch-2.7.1/src/inp.c
&& (file_type & S_IFMT) == (instat.st_mode & S_IFMT)))
diff -up patch-2.7.1/src/Makefile.am.selinux patch-2.7.1/src/Makefile.am
--- patch-2.7.1/src/Makefile.am.selinux 2012-09-14 10:15:41.000000000 +0100
-+++ patch-2.7.1/src/Makefile.am 2015-01-20 12:26:32.914110148 +0000
++++ patch-2.7.1/src/Makefile.am 2015-01-20 13:29:30.388915881 +0000
@@ -34,7 +34,7 @@ patch_SOURCES = \
AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib
@@ -61,7 +61,7 @@ diff -up patch-2.7.1/src/Makefile.am.selinux patch-2.7.1/src/Makefile.am
patch_SOURCES += merge.c
diff -up patch-2.7.1/src/Makefile.in.selinux patch-2.7.1/src/Makefile.in
--- patch-2.7.1/src/Makefile.in.selinux 2012-09-28 17:41:31.000000000 +0100
-+++ patch-2.7.1/src/Makefile.in 2015-01-20 12:26:32.915110151 +0000
++++ patch-2.7.1/src/Makefile.in 2015-01-20 13:29:30.389915884 +0000
@@ -981,7 +981,7 @@ patch_SOURCES = bestmatch.h common.h inp
AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib \
$(am__append_2)
@@ -72,8 +72,8 @@ diff -up patch-2.7.1/src/Makefile.in.selinux patch-2.7.1/src/Makefile.in
all: all-am
diff -up patch-2.7.1/src/patch.c.selinux patch-2.7.1/src/patch.c
---- patch-2.7.1/src/patch.c.selinux 2015-01-20 12:26:32.910110134 +0000
-+++ patch-2.7.1/src/patch.c 2015-01-20 12:26:32.915110151 +0000
+--- patch-2.7.1/src/patch.c.selinux 2015-01-20 13:29:30.383915863 +0000
++++ patch-2.7.1/src/patch.c 2015-01-20 13:29:30.389915884 +0000
@@ -257,19 +257,19 @@ main (int argc, char **argv)
if (! strcmp (inname, outname))
{
@@ -125,8 +125,8 @@ diff -up patch-2.7.1/src/patch.c.selinux patch-2.7.1/src/patch.c
st = &st_tmp;
}
diff -up patch-2.7.1/src/pch.c.selinux patch-2.7.1/src/pch.c
---- patch-2.7.1/src/pch.c.selinux 2015-01-20 12:26:32.911110138 +0000
-+++ patch-2.7.1/src/pch.c 2015-01-20 12:26:32.916110154 +0000
+--- patch-2.7.1/src/pch.c.selinux 2015-01-20 13:29:30.385915870 +0000
++++ patch-2.7.1/src/pch.c 2015-01-20 13:29:30.389915884 +0000
@@ -1,6 +1,6 @@
/* reading patches */
@@ -144,7 +144,7 @@ diff -up patch-2.7.1/src/pch.c.selinux patch-2.7.1/src/pch.c
if (inerrno)
{
perror (inname);
-@@ -522,6 +522,7 @@ intuit_diff_type (bool need_header, mode
+@@ -445,6 +445,7 @@ intuit_diff_type (bool need_header, mode
bool extended_headers = false;
enum nametype i;
struct stat st[3];
@@ -152,7 +152,7 @@ diff -up patch-2.7.1/src/pch.c.selinux patch-2.7.1/src/pch.c
int stat_errno[3];
int version_controlled[3];
enum diff retval;
-@@ -561,6 +562,7 @@ intuit_diff_type (bool need_header, mode
+@@ -484,6 +485,7 @@ intuit_diff_type (bool need_header, mode
version_controlled[OLD] = -1;
version_controlled[NEW] = -1;
version_controlled[INDEX] = -1;
@@ -160,7 +160,7 @@ diff -up patch-2.7.1/src/pch.c.selinux patch-2.7.1/src/pch.c
p_rfc934_nesting = 0;
p_timestamp[OLD].tv_sec = p_timestamp[NEW].tv_sec = -1;
p_says_nonexistent[OLD] = p_says_nonexistent[NEW] = 0;
-@@ -968,7 +970,7 @@ intuit_diff_type (bool need_header, mode
+@@ -891,7 +893,7 @@ intuit_diff_type (bool need_header, mode
}
else
{
@@ -169,7 +169,7 @@ diff -up patch-2.7.1/src/pch.c.selinux patch-2.7.1/src/pch.c
if (! stat_errno[i])
{
if (lookup_file_id (&st[i]) == DELETE_LATER)
-@@ -1007,7 +1009,7 @@ intuit_diff_type (bool need_header, mode
+@@ -930,7 +932,7 @@ intuit_diff_type (bool need_header, mode
if (cs)
{
if (version_get (p_name[i], cs, false, readonly,
@@ -178,7 +178,7 @@ diff -up patch-2.7.1/src/pch.c.selinux patch-2.7.1/src/pch.c
stat_errno[i] = 0;
else
version_controlled[i] = 0;
-@@ -1060,7 +1062,7 @@ intuit_diff_type (bool need_header, mode
+@@ -983,7 +985,7 @@ intuit_diff_type (bool need_header, mode
{
if (inname)
{
@@ -187,7 +187,7 @@ diff -up patch-2.7.1/src/pch.c.selinux patch-2.7.1/src/pch.c
if (inerrno || (instat.st_mode & S_IFMT) == file_type)
maybe_reverse (inname, inerrno, inerrno || instat.st_size == 0);
}
-@@ -1073,8 +1075,14 @@ intuit_diff_type (bool need_header, mode
+@@ -996,8 +998,14 @@ intuit_diff_type (bool need_header, mode
inerrno = stat_errno[i];
invc = version_controlled[i];
instat = st[i];
@@ -203,8 +203,8 @@ diff -up patch-2.7.1/src/pch.c.selinux patch-2.7.1/src/pch.c
}
diff -up patch-2.7.1/src/util.c.selinux patch-2.7.1/src/util.c
---- patch-2.7.1/src/util.c.selinux 2015-01-20 12:26:32.912110141 +0000
-+++ patch-2.7.1/src/util.c 2015-01-20 12:26:32.917110158 +0000
+--- patch-2.7.1/src/util.c.selinux 2015-01-20 13:29:30.386915874 +0000
++++ patch-2.7.1/src/util.c 2015-01-20 13:29:30.390915888 +0000
@@ -294,6 +294,19 @@ set_file_attributes (char const *to, enu
S_ISLNK (mode) ? "symbolic link" : "file",
quotearg (to));
@@ -225,7 +225,7 @@ diff -up patch-2.7.1/src/util.c.selinux patch-2.7.1/src/util.c
}
static void
-@@ -440,7 +453,7 @@ move_file (char const *from, bool *from_
+@@ -494,7 +507,7 @@ move_file (char const *from, bool *from_
struct stat to_st;
int to_errno;
@@ -234,7 +234,7 @@ diff -up patch-2.7.1/src/util.c.selinux patch-2.7.1/src/util.c
if (backup)
create_backup (to, to_errno ? NULL : &to_st, false);
if (! to_errno)
-@@ -817,7 +830,8 @@ version_controller (char const *filename
+@@ -871,7 +884,8 @@ version_controller (char const *filename
Return true if successful. */
bool
version_get (char const *filename, char const *cs, bool exists, bool readonly,
@@ -244,7 +244,7 @@ diff -up patch-2.7.1/src/util.c.selinux patch-2.7.1/src/util.c
{
if (patch_get < 0)
{
-@@ -842,6 +856,13 @@ version_get (char const *filename, char
+@@ -896,6 +910,13 @@ version_get (char const *filename, char
fatal ("Can't get file %s from %s", quotearg (filename), cs);
if (stat (filename, filestat) != 0)
pfatal ("%s", quotearg (filename));
@@ -258,7 +258,7 @@ diff -up patch-2.7.1/src/util.c.selinux patch-2.7.1/src/util.c
}
return 1;
-@@ -1660,10 +1681,26 @@ make_tempfile (char const **name, char l
+@@ -1714,12 +1735,28 @@ make_tempfile (char const **name, char l
}
}
@@ -287,9 +287,11 @@ diff -up patch-2.7.1/src/util.c.selinux patch-2.7.1/src/util.c
- return xstat (filename, st) == 0 ? 0 : errno;
+ return errno;
}
+
+ /* Check if we are in the root of a particular filesystem namespace ("/" on
diff -up patch-2.7.1/src/util.h.selinux patch-2.7.1/src/util.h
---- patch-2.7.1/src/util.h.selinux 2012-09-21 21:21:16.000000000 +0100
-+++ patch-2.7.1/src/util.h 2015-01-20 12:26:32.917110158 +0000
+--- patch-2.7.1/src/util.h.selinux 2015-01-20 13:29:30.386915874 +0000
++++ patch-2.7.1/src/util.h 2015-01-20 13:30:14.653081617 +0000
@@ -45,7 +45,7 @@ char *parse_name (char const *, int, cha
char *savebuf (char const *, size_t);
char *savestr (char const *);
@@ -299,12 +301,13 @@ diff -up patch-2.7.1/src/util.h.selinux patch-2.7.1/src/util.h
int create_file (char const *, int, mode_t, bool);
int systemic (char const *);
char *format_linenum (char[LINENUM_LENGTH_BOUND + 1], lin);
-@@ -68,13 +68,14 @@ void insert_file_id (struct stat const *
+@@ -68,14 +68,15 @@ 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 cwd_is_root (char const *);
enum file_attributes {
FA_TIMES = 1,
diff --git a/patch.spec b/patch.spec
index 7609a46..fe54e5f 100644
--- a/patch.spec
+++ b/patch.spec
@@ -1,7 +1,7 @@
Summary: Utility for modifying/upgrading files
Name: patch
Version: 2.7.1
-Release: 10%{?dist}
+Release: 11%{?dist}
License: GPLv3+
URL: http://www.gnu.org/software/patch/patch.html
Group: Development/Tools
@@ -71,7 +71,7 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/*/*
%changelog
-* Tue Jan 20 2015 Tim Waugh <twaugh at redhat.com> - 2.7.1-10
+* Tue Jan 20 2015 Tim Waugh <twaugh at redhat.com> - 2.7.1-11
- Apply upstream patch to fix directory traversal via symlinks
(bug #1182157, CVE-2015-1196).
More information about the scm-commits
mailing list