diff --git a/patch-lineno-overflow.patch b/patch-lineno-overflow.patch new file mode 100644 index 0000000..dc1ad02 --- /dev/null +++ b/patch-lineno-overflow.patch @@ -0,0 +1,125 @@ +diff -up patch-2.7.1/src/common.h.lineno-overflow patch-2.7.1/src/common.h +--- patch-2.7.1/src/common.h.lineno-overflow 2012-09-28 15:00:04.000000000 +0100 ++++ patch-2.7.1/src/common.h 2015-01-20 14:47:37.262280623 +0000 +@@ -39,6 +39,7 @@ + #elif HAVE_STDINT_H + # include + #endif ++#include + + #include + /* CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given +@@ -68,6 +69,9 @@ + + typedef off_t lin; /* must be signed */ + ++#define LINENUM_MIN TYPE_MINIMUM (lin) ++#define LINENUM_MAX TYPE_MAXIMUM (lin) ++ + /* globals */ + + XTERN char *buf; /* general purpose buffer */ +diff -up patch-2.7.1/src/pch.c.lineno-overflow patch-2.7.1/src/pch.c +--- patch-2.7.1/src/pch.c.lineno-overflow 2015-01-20 14:46:49.533109967 +0000 ++++ patch-2.7.1/src/pch.c 2015-01-20 14:47:37.264280630 +0000 +@@ -1294,6 +1294,8 @@ another_hunk (enum diff difftype, bool r + s++; + scan_linenum (s, &p_ptrn_lines); + p_ptrn_lines += 1 - p_first; ++ if (p_ptrn_lines < 0) ++ malformed (); + } + else if (p_first) + p_ptrn_lines = 1; +@@ -1301,6 +1303,9 @@ another_hunk (enum diff difftype, bool r + p_ptrn_lines = 0; + p_first = 1; + } ++ if (p_first >= LINENUM_MAX - p_ptrn_lines || ++ p_ptrn_lines >= LINENUM_MAX - 6) ++ malformed (); + p_max = p_ptrn_lines + 6; /* we need this much at least */ + while (p_max + 1 >= hunkmax) + if (! grow_hunkmax ()) +@@ -1370,6 +1375,8 @@ another_hunk (enum diff difftype, bool r + while (! ISDIGIT (*s)); + scan_linenum (s, &p_repl_lines); + p_repl_lines += 1 - p_newfirst; ++ if (p_repl_lines < 0) ++ malformed (); + } + else if (p_newfirst) + p_repl_lines = 1; +@@ -1378,6 +1385,9 @@ another_hunk (enum diff difftype, bool r + p_repl_lines = 0; + p_newfirst = 1; + } ++ if (p_newfirst >= LINENUM_MAX - p_repl_lines || ++ p_repl_lines >= LINENUM_MAX - p_end) ++ malformed (); + p_max = p_repl_lines + p_end; + while (p_max + 1 >= hunkmax) + if (! grow_hunkmax ()) +@@ -1617,6 +1627,8 @@ another_hunk (enum diff difftype, bool r + s = scan_linenum (s + 1, &p_ptrn_lines); + else + p_ptrn_lines = 1; ++ if (p_first >= LINENUM_MAX - p_ptrn_lines) ++ malformed (); + if (*s == ' ') s++; + if (*s != '+') + malformed (); +@@ -1625,6 +1637,8 @@ another_hunk (enum diff difftype, bool r + s = scan_linenum (s + 1, &p_repl_lines); + else + p_repl_lines = 1; ++ if (p_newfirst >= LINENUM_MAX - p_repl_lines) ++ malformed (); + if (*s == ' ') s++; + if (*s++ != '@') + malformed (); +@@ -1640,6 +1654,8 @@ another_hunk (enum diff difftype, bool r + p_first++; /* do append rather than insert */ + if (!p_repl_lines) + p_newfirst++; ++ if (p_ptrn_lines >= LINENUM_MAX - (p_repl_lines + 1)) ++ malformed (); + p_max = p_ptrn_lines + p_repl_lines + 1; + while (p_max + 1 >= hunkmax) + if (! grow_hunkmax ()) +@@ -1776,6 +1792,8 @@ another_hunk (enum diff difftype, bool r + } + else + p_ptrn_lines = (*s != 'a'); ++ if (p_first >= LINENUM_MAX - p_ptrn_lines) ++ malformed (); + hunk_type = *s; + if (hunk_type == 'a') + p_first++; /* do append rather than insert */ +@@ -1784,17 +1802,23 @@ another_hunk (enum diff difftype, bool r + scan_linenum (s + 1, &max); + else + max = min; ++ if (min > max || max - min == LINENUM_MAX) ++ malformed (); + if (hunk_type == 'd') + min++; +- p_end = p_ptrn_lines + 1 + max - min + 1; ++ p_newfirst = min; ++ p_repl_lines = max - min + 1; ++ if (p_newfirst >= LINENUM_MAX - p_repl_lines) ++ malformed (); ++ if (p_ptrn_lines >= LINENUM_MAX - (p_repl_lines + 1)) ++ malformed (); ++ p_end = p_ptrn_lines + p_repl_lines + 1; + while (p_end + 1 >= hunkmax) + if (! grow_hunkmax ()) + { + p_end = -1; + return -1; + } +- p_newfirst = min; +- p_repl_lines = max - min + 1; + sprintf (buf, "*** %s,%s\n", + format_linenum (numbuf0, p_first), + format_linenum (numbuf1, p_first + p_ptrn_lines - 1)); diff --git a/patch.spec b/patch.spec index fe54e5f..c4b1f63 100644 --- a/patch.spec +++ b/patch.spec @@ -1,7 +1,7 @@ Summary: Utility for modifying/upgrading files Name: patch Version: 2.7.1 -Release: 11%{?dist} +Release: 12%{?dist} License: GPLv3+ URL: http://www.gnu.org/software/patch/patch.html Group: Development/Tools @@ -10,6 +10,7 @@ Patch1: patch-remove-empty-dir.patch Patch2: patch-args.patch Patch3: patch-args-segfault.patch Patch4: patch-CVE-2015-1196.patch +Patch5: patch-lineno-overflow.patch Patch100: patch-selinux.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -43,6 +44,9 @@ applications. # (bug #1182157, CVE-2015-1196). %patch4 -p1 -b .CVE-2015-1196 +# Apply upstream patch to fix line numbering integer overflow. +%patch5 -p1 -b .lineno-overflow + # SELinux support. %patch100 -p1 -b .selinux @@ -71,6 +75,9 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/*/* %changelog +* Tue Jan 20 2015 Tim Waugh - 2.7.1-12 +- Apply upstream patch to fix line numbering integer overflow. + * Tue Jan 20 2015 Tim Waugh - 2.7.1-11 - Apply upstream patch to fix directory traversal via symlinks (bug #1182157, CVE-2015-1196).