From 3298b107f6b56decdaa68ed6fa84cc0948872edc Mon Sep 17 00:00:00 2001 From: lubing6 Date: Wed, 18 Mar 2020 15:44:07 +0800 Subject: [PATCH] fix memory leak --- patch-selinux.patch | 326 ++++++++++++++++++++++++++++++++++++++++++++ patch.spec | 9 +- 2 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 patch-selinux.patch diff --git a/patch-selinux.patch b/patch-selinux.patch new file mode 100644 index 0000000..7c16a1a --- /dev/null +++ b/patch-selinux.patch @@ -0,0 +1,326 @@ +diff -up patch-2.7.6/src/common.h.selinux patch-2.7.6/src/common.h +--- patch-2.7.6/src/common.h.selinux 2018-02-03 12:41:49.000000000 +0000 ++++ patch-2.7.6/src/common.h 2018-02-12 12:29:44.415225377 +0000 +@@ -30,6 +30,8 @@ + #include + #include + ++#include ++ + #include + + #include +@@ -84,6 +86,7 @@ XTERN char *outfile; + XTERN int inerrno; + XTERN int invc; + XTERN struct stat instat; ++XTERN security_context_t incontext; + XTERN bool dry_run; + XTERN bool posixly_correct; + +diff -up patch-2.7.6/src/inp.c.selinux patch-2.7.6/src/inp.c +--- patch-2.7.6/src/inp.c.selinux 2017-09-04 12:34:16.000000000 +0100 ++++ patch-2.7.6/src/inp.c 2018-02-12 12:29:44.415225377 +0000 +@@ -145,7 +145,7 @@ get_input_file (char const *filename, ch + char *getbuf; + + if (inerrno == -1) +- inerrno = stat_file (filename, &instat); ++ inerrno = stat_file (filename, &instat, &incontext); + + /* Perhaps look for RCS or SCCS versions. */ + if (S_ISREG (file_type) +@@ -190,7 +190,7 @@ get_input_file (char const *filename, ch + } + + if (cs && version_get (filename, cs, ! inerrno, elsewhere, getbuf, +- &instat)) ++ &instat, &incontext)) + inerrno = 0; + + free (getbuf); +@@ -201,6 +201,7 @@ get_input_file (char const *filename, ch + { + instat.st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; + instat.st_size = 0; ++ incontext = NULL; + } + else if (! ((S_ISREG (file_type) || S_ISLNK (file_type)) + && (file_type & S_IFMT) == (instat.st_mode & S_IFMT))) +diff -up patch-2.7.6/src/Makefile.am.selinux patch-2.7.6/src/Makefile.am +--- patch-2.7.6/src/Makefile.am.selinux 2017-09-04 12:34:16.000000000 +0100 ++++ patch-2.7.6/src/Makefile.am 2018-02-12 12:29:44.415225377 +0000 +@@ -37,7 +37,7 @@ patch_SOURCES = \ + + AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib + patch_LDADD = $(LDADD) $(top_builddir)/lib/libpatch.a $(LIB_CLOCK_GETTIME) \ +- $(LIB_XATTR) $(LIB_EACCESS) ++ $(LIB_XATTR) $(LIB_EACCESS) -lselinux + + if ENABLE_MERGE + patch_SOURCES += merge.c +diff -up patch-2.7.6/src/Makefile.in.selinux patch-2.7.6/src/Makefile.in +--- patch-2.7.6/src/Makefile.in.selinux 2018-02-03 13:33:56.000000000 +0000 ++++ patch-2.7.6/src/Makefile.in 2018-02-12 12:29:44.415225377 +0000 +@@ -1147,7 +1147,7 @@ patch_SOURCES = bestmatch.h common.h inp + AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib \ + $(am__append_2) + patch_LDADD = $(LDADD) $(top_builddir)/lib/libpatch.a $(LIB_CLOCK_GETTIME) \ +- $(LIB_XATTR) $(LIB_EACCESS) ++ $(LIB_XATTR) $(LIB_EACCESS) -lselinux + + all: all-am + +diff -up patch-2.7.6/src/patch.c.selinux patch-2.7.6/src/patch.c +--- patch-2.7.6/src/patch.c.selinux 2018-02-03 12:41:49.000000000 +0000 ++++ patch-2.7.6/src/patch.c 2018-02-12 12:30:27.315164138 +0000 +@@ -269,19 +269,19 @@ main (int argc, char **argv) + if (! strcmp (inname, outname)) + { + if (inerrno == -1) +- inerrno = stat_file (inname, &instat); ++ inerrno = stat_file (inname, &instat, NULL); + outstat = instat; + outerrno = inerrno; + } + else +- outerrno = stat_file (outname, &outstat); ++ outerrno = stat_file (outname, &outstat, NULL); + + if (! outerrno) + { + if (has_queued_output (&outstat)) + { + output_files (&outstat); +- outerrno = stat_file (outname, &outstat); ++ outerrno = stat_file (outname, &outstat, NULL); + inerrno = -1; + } + if (! outerrno) +@@ -598,7 +598,7 @@ main (int argc, char **argv) + } + else + { +- attr |= FA_IDS | FA_MODE | FA_XATTRS; ++ attr |= FA_IDS | FA_MODE | FA_XATTRS | FA_SECCONTEXT; + set_file_attributes (TMPOUTNAME, attr, inname, &instat, + mode, &new_time); + } +@@ -658,7 +658,7 @@ main (int argc, char **argv) + struct stat oldst; + int olderrno; + +- olderrno = stat_file (rej, &oldst); ++ olderrno = stat_file (rej, &oldst, NULL); + if (olderrno && olderrno != ENOENT) + write_fatal (); + if (! olderrno && lookup_file_id (&oldst) == CREATED) +@@ -1790,7 +1790,7 @@ delete_file_later (const char *name, con + + if (! st) + { +- if (stat_file (name, &st_tmp) != 0) ++ if (stat_file (name, &st_tmp, NULL) != 0) + pfatal ("Can't get file attributes of %s %s", "file", name); + st = &st_tmp; + } +diff -up patch-2.7.6/src/pch.c.selinux patch-2.7.6/src/pch.c +--- patch-2.7.6/src/pch.c.selinux 2018-02-03 12:41:49.000000000 +0000 ++++ patch-2.7.6/src/pch.c 2018-02-12 12:29:44.416225375 +0000 +@@ -1,6 +1,6 @@ + /* reading patches */ + +-/* Copyright (C) 1986, 1987, 1988 Larry Wall ++/* Copyright (C) 1986, 1987, 1988, 2012 Larry Wall + + Copyright (C) 1990-1993, 1997-2003, 2006, 2009-2012 Free Software + Foundation, Inc. +@@ -296,7 +296,7 @@ there_is_another_patch (bool need_header + if (t > buf + 1 && *(t - 1) == '\n') + { + inname = xmemdup0 (buf, t - buf - 1); +- inerrno = stat_file (inname, &instat); ++ inerrno = stat_file (inname, &instat, &incontext); + if (inerrno) + { + perror (inname); +@@ -433,6 +433,7 @@ intuit_diff_type (bool need_header, mode + bool extended_headers = false; + enum nametype i; + struct stat st[3]; ++ security_context_t con[3]; + int stat_errno[3]; + int version_controlled[3]; + enum diff retval; +@@ -473,6 +474,7 @@ intuit_diff_type (bool need_header, mode + version_controlled[OLD] = -1; + version_controlled[NEW] = -1; + version_controlled[INDEX] = -1; ++ con[OLD] = con[NEW] = con[INDEX] = NULL; + p_rfc934_nesting = 0; + p_timestamp[OLD].tv_sec = p_timestamp[NEW].tv_sec = -1; + p_says_nonexistent[OLD] = p_says_nonexistent[NEW] = 0; +@@ -883,7 +885,7 @@ intuit_diff_type (bool need_header, mode + } + else + { +- stat_errno[i] = stat_file (p_name[i], &st[i]); ++ stat_errno[i] = stat_file (p_name[i], &st[i], &con[i]); + if (! stat_errno[i]) + { + if (lookup_file_id (&st[i]) == DELETE_LATER) +@@ -922,7 +924,7 @@ intuit_diff_type (bool need_header, mode + if (cs) + { + if (version_get (p_name[i], cs, false, readonly, +- getbuf, &st[i])) ++ getbuf, &st[i], &con[i])) + stat_errno[i] = 0; + else + version_controlled[i] = 0; +@@ -985,7 +987,7 @@ intuit_diff_type (bool need_header, mode + { + if (inname) + { +- inerrno = stat_file (inname, &instat); ++ inerrno = stat_file (inname, &instat, &incontext); + if (inerrno || (instat.st_mode & S_IFMT) == file_type) + maybe_reverse (inname, inerrno, inerrno || instat.st_size == 0); + } +@@ -998,8 +1000,14 @@ intuit_diff_type (bool need_header, mode + inerrno = stat_errno[i]; + invc = version_controlled[i]; + instat = st[i]; ++ incontext = con[i]; ++ con[i] = NULL; + } + ++ for (i = OLD; i <= INDEX; i++) ++ if (con[i]) ++ freecon (con[i]); ++ + return retval; + } + +diff -up patch-2.7.6/src/util.c.selinux patch-2.7.6/src/util.c +--- patch-2.7.6/src/util.c.selinux 2018-02-03 12:41:49.000000000 +0000 ++++ patch-2.7.6/src/util.c 2018-02-12 12:29:44.417225374 +0000 +@@ -300,6 +300,23 @@ set_file_attributes (char const *to, enu + S_ISLNK (mode) ? "symbolic link" : "file", + quotearg (to)); + } ++ if (attr & FA_SECCONTEXT) ++ { ++ security_context_t outcontext; ++ if (incontext && getfilecon (to, &outcontext) != -1 && outcontext) ++ { ++ if (strcmp (outcontext, incontext) && ++ setfilecon (to, incontext) != 0) ++ { ++ freecon (outcontext); ++ if (errno != ENOTSUP && errno != EPERM) ++ pfatal ("Can't set security context on file %s", ++ quotearg (to)); ++ } ++ else ++ freecon (outcontext); ++ } ++ } + } + + static void +@@ -446,7 +463,7 @@ move_file (char const *from, bool *from_ + struct stat to_st; + int to_errno; + +- to_errno = stat_file (to, &to_st); ++ to_errno = stat_file (to, &to_st, NULL); + if (backup) + create_backup (to, to_errno ? NULL : &to_st, false); + if (! to_errno) +@@ -818,7 +835,8 @@ version_controller (char const *filename + Return true if successful. */ + bool + version_get (char const *filename, char const *cs, bool exists, bool readonly, +- char const *getbuf, struct stat *filestat) ++ char const *getbuf, struct stat *filestat, ++ security_context_t *filecontext) + { + if (patch_get < 0) + { +@@ -843,6 +861,13 @@ version_get (char const *filename, char + fatal ("Can't get file %s from %s", quotearg (filename), cs); + if (safe_stat (filename, filestat) != 0) + pfatal ("%s", quotearg (filename)); ++ if (filecontext && getfilecon (filename, filecontext) == -1) ++ { ++ if (errno == ENODATA || errno == ENOTSUP) ++ *filecontext = NULL; ++ else ++ pfatal ("%s", quotearg (filename)); ++ } + } + + return 1; +@@ -1670,12 +1695,28 @@ make_tempfile (char const **name, char l + return fd; + } + +-int stat_file (char const *filename, struct stat *st) ++int stat_file (char const *filename, struct stat *st, security_context_t *con) + { + int (*xstat)(char const *, struct stat *) = + follow_symlinks ? safe_stat : safe_lstat; ++ int (*xgetfilecon)(char const *, security_context_t *) = ++ follow_symlinks ? getfilecon : lgetfilecon; ++ ++ if (xstat (filename, st) == 0) ++ { ++ if (con) ++ { ++ if (xgetfilecon (filename, con) != -1 || ++ errno == ENODATA || errno == ENOTSUP) ++ return 0; + +- return xstat (filename, st) == 0 ? 0 : errno; ++ *con = NULL; ++ } ++ else ++ return 0; ++ } ++ ++ return errno; + } + + /* Check if a filename is relative and free of ".." components. +diff -up patch-2.7.6/src/util.h.selinux patch-2.7.6/src/util.h +--- patch-2.7.6/src/util.h.selinux 2018-02-03 12:41:49.000000000 +0000 ++++ patch-2.7.6/src/util.h 2018-02-12 12:30:08.533190949 +0000 +@@ -44,7 +44,7 @@ char *parse_name (char const *, int, cha + char *savebuf (char const *, size_t); + char *savestr (char const *); + char const *version_controller (char const *, bool, struct stat const *, char **, char **); +-bool version_get (char const *, char const *, bool, bool, char const *, struct stat *); ++bool version_get (char const *, char const *, bool, bool, char const *, struct stat *, security_context_t *); + int create_file (char const *, int, mode_t, bool); + int systemic (char const *); + char *format_linenum (char[LINENUM_LENGTH_BOUND + 1], lin); +@@ -67,7 +67,7 @@ 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 filename_is_safe (char const *) _GL_ATTRIBUTE_PURE; + bool cwd_is_root (char const *); + +@@ -75,7 +75,8 @@ enum file_attributes { + FA_TIMES = 1, + FA_IDS = 2, + FA_MODE = 4, +- FA_XATTRS = 8 ++ FA_XATTRS = 8, ++ FA_SECCONTEXT = 16 + }; + + void set_file_attributes (char const *, enum file_attributes, char const *, diff --git a/patch.spec b/patch.spec index 250e24c..7f7a5a0 100644 --- a/patch.spec +++ b/patch.spec @@ -1,6 +1,6 @@ Name: patch Version: 2.7.6 -Release: 11 +Release: 12 Summary: Utiliity which applies a patch file to original files. License: GPLv3+ URL: http://www.gnu.org/software/patch/patch.html @@ -13,6 +13,7 @@ Patch4: Don-t-leak-temporary-file-on-failed-multi-file-ed-st.patch Patch5: Fix-swapping-fake-lines-in-pch_swap.patch Patch6: CVE-2018-20969-and-CVE-2019-13638.patch Patch7: CVE-2019-13636.patch +Patch8: patch-selinux.patch BuildRequires: gcc libselinux-devel libattr-devel ed Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-root @@ -55,6 +56,12 @@ make check %{_mandir}/man1/* %changelog +* Wed Mar 18 2020 openEuler Buildteam - 2.7.6-12 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:Fix memory leak + * Mon Feb 3 2020 openEuler Buildteam - 2.7.6-11 - Type:CVE - ID:NA