backport CVE-2015-1197 and following 2 bugfix patches. Delete revert-CVE-2015-1197.patch
because new CVE patch will fix the problem of old CVE patch, so we don't need to revert old CVE patch. (cherry picked from commit bdaa060cf319507a37e75c5b96c647d2fd2bc9bd)
This commit is contained in:
parent
14ec7171e9
commit
7370c39eae
259
backport-CVE-2015-1197.patch
Normal file
259
backport-CVE-2015-1197.patch
Normal file
@ -0,0 +1,259 @@
|
||||
From 376d663340a9dc91c91a5849e5713f07571c1628 Mon Sep 17 00:00:00 2001
|
||||
From: Sergey Poznyakoff <gray@gnu.org>
|
||||
Date: Thu, 27 Apr 2023 15:14:23 +0300
|
||||
Subject: Fix 45b0ee2b407913c533f7ded8d6f8cbeec16ff6ca.
|
||||
|
||||
The commit in question brought in more problems than solutions. To
|
||||
properly fix the issue, use symlink placeholders, modelled after
|
||||
delayed symlinks in tar.
|
||||
|
||||
* src/copyin.c (symlink_placeholder)
|
||||
(replace_symlink_placeholders): New functions.
|
||||
(copyin_link): Create symlink placeholder if --no-absolute-filenames
|
||||
was given.
|
||||
(process_copy_in): Replace placeholders after extraction.
|
||||
* tests/CVE-2015-1197.at: Update. Don't use /tmp.
|
||||
|
||||
Reference:http://git.savannah.gnu.org/cgit/cpio.git/commit/?id=376d663340a9dc91c91a5849e5713f07571c1628
|
||||
Conflict:NA
|
||||
|
||||
---
|
||||
src/copyin.c | 173 ++++++++++++++++++++++++++++++++++++++++++-------
|
||||
tests/CVE-2015-1197.at | 7 +-
|
||||
2 files changed, 153 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/src/copyin.c b/src/copyin.c
|
||||
index 60cef9d..5ed2db6 100644
|
||||
--- a/src/copyin.c
|
||||
+++ b/src/copyin.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#ifndef FNM_PATHNAME
|
||||
# include <fnmatch.h>
|
||||
#endif
|
||||
+#include <hash.h>
|
||||
|
||||
#ifndef HAVE_LCHOWN
|
||||
# define lchown(f,u,g) 0
|
||||
@@ -620,6 +621,136 @@ copyin_device (struct cpio_file_stat* file_hdr)
|
||||
file_hdr->c_mtime);
|
||||
}
|
||||
|
||||
+struct delayed_link
|
||||
+ {
|
||||
+ /* The device and inode number of the placeholder. */
|
||||
+ dev_t dev;
|
||||
+ ino_t ino;
|
||||
+
|
||||
+ /* The desired link metadata. */
|
||||
+ mode_t mode;
|
||||
+ uid_t uid;
|
||||
+ gid_t gid;
|
||||
+ time_t mtime;
|
||||
+
|
||||
+ /* Link source and target names. */
|
||||
+ char *source;
|
||||
+ char target[1];
|
||||
+ };
|
||||
+
|
||||
+static Hash_table *delayed_link_table;
|
||||
+
|
||||
+static size_t
|
||||
+dl_hash (void const *entry, size_t table_size)
|
||||
+{
|
||||
+ struct delayed_link const *dl = entry;
|
||||
+ uintmax_t n = dl->dev;
|
||||
+ int nshift = (sizeof (n) - sizeof (dl->dev)) * CHAR_BIT;
|
||||
+ if (0 < nshift)
|
||||
+ n <<= nshift;
|
||||
+ n ^= dl->ino;
|
||||
+ return n % table_size;
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+dl_compare (void const *a, void const *b)
|
||||
+{
|
||||
+ struct delayed_link const *da = a, *db = b;
|
||||
+ return (da->dev == db->dev) & (da->ino == db->ino);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+symlink_placeholder (char *oldpath, char *newpath, struct cpio_file_stat *file_stat)
|
||||
+{
|
||||
+ int fd = open (newpath, O_WRONLY | O_CREAT | O_EXCL, 0);
|
||||
+ struct stat st;
|
||||
+ struct delayed_link *p;
|
||||
+ size_t newlen = strlen (newpath);
|
||||
+
|
||||
+ if (fd < 0)
|
||||
+ {
|
||||
+ open_error (newpath);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (fstat (fd, &st) != 0)
|
||||
+ {
|
||||
+ stat_error (newpath);
|
||||
+ close (fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ close (fd);
|
||||
+
|
||||
+ p = xmalloc (sizeof (*p) + strlen (oldpath) + newlen + 1);
|
||||
+ p->dev = st.st_dev;
|
||||
+ p->ino = st.st_ino;
|
||||
+
|
||||
+ p->mode = file_stat->c_mode;
|
||||
+ p->uid = file_stat->c_uid;
|
||||
+ p->gid = file_stat->c_gid;
|
||||
+ p->mtime = file_stat->c_mtime;
|
||||
+
|
||||
+ strcpy (p->target, newpath);
|
||||
+ p->source = p->target + newlen + 1;
|
||||
+ strcpy (p->source, oldpath);
|
||||
+
|
||||
+ if (!((delayed_link_table
|
||||
+ || (delayed_link_table = hash_initialize (0, 0, dl_hash,
|
||||
+ dl_compare, free)))
|
||||
+ && hash_insert (delayed_link_table, p)))
|
||||
+ xalloc_die ();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+replace_symlink_placeholders (void)
|
||||
+{
|
||||
+ struct delayed_link *dl;
|
||||
+
|
||||
+ if (!delayed_link_table)
|
||||
+ return;
|
||||
+ for (dl = hash_get_first (delayed_link_table);
|
||||
+ dl;
|
||||
+ dl = hash_get_next (delayed_link_table, dl))
|
||||
+ {
|
||||
+ struct stat st;
|
||||
+
|
||||
+ /* Make sure the placeholder file is still there. If not,
|
||||
+ don't create a link, as the placeholder was probably
|
||||
+ removed by a later extraction. */
|
||||
+ if (lstat (dl->target, &st) == 0
|
||||
+ && st.st_dev == dl->dev
|
||||
+ && st.st_ino == dl->ino)
|
||||
+ {
|
||||
+ if (unlink (dl->target))
|
||||
+ unlink_error (dl->target);
|
||||
+ else
|
||||
+ {
|
||||
+ int res = UMASKED_SYMLINK (dl->source, dl->target, dl->mode);
|
||||
+ if (res < 0 && create_dir_flag)
|
||||
+ {
|
||||
+ create_all_directories (dl->target);
|
||||
+ res = UMASKED_SYMLINK (dl->source, dl->target, dl->mode);
|
||||
+ }
|
||||
+ if (res < 0)
|
||||
+ symlink_error (dl->source, dl->target);
|
||||
+ else if (!no_chown_flag)
|
||||
+ {
|
||||
+ uid_t uid = set_owner_flag ? set_owner : dl->uid;
|
||||
+ gid_t gid = set_group_flag ? set_group : dl->gid;
|
||||
+ if (lchown (dl->target, uid, gid) < 0 && errno != EPERM)
|
||||
+ chown_error_details (dl->target, uid, gid);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ hash_free (delayed_link_table);
|
||||
+ delayed_link_table = NULL;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
copyin_link (struct cpio_file_stat *file_hdr, int in_file_des)
|
||||
{
|
||||
@@ -645,29 +776,26 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des)
|
||||
link_name = xstrdup (file_hdr->c_tar_linkname);
|
||||
}
|
||||
|
||||
- cpio_safer_name_suffix (link_name, true, !no_abs_paths_flag, false);
|
||||
-
|
||||
- res = UMASKED_SYMLINK (link_name, file_hdr->c_name,
|
||||
- file_hdr->c_mode);
|
||||
- if (res < 0 && create_dir_flag)
|
||||
- {
|
||||
- create_all_directories (file_hdr->c_name);
|
||||
- res = UMASKED_SYMLINK (link_name, file_hdr->c_name, file_hdr->c_mode);
|
||||
- }
|
||||
- if (res < 0)
|
||||
- {
|
||||
- error (0, errno, _("%s: Cannot symlink to %s"),
|
||||
- quotearg_colon (link_name), quote_n (1, file_hdr->c_name));
|
||||
- free (link_name);
|
||||
- return;
|
||||
- }
|
||||
- if (!no_chown_flag)
|
||||
+ if (no_abs_paths_flag)
|
||||
+ symlink_placeholder (link_name, file_hdr->c_name, file_hdr);
|
||||
+ else
|
||||
{
|
||||
- uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid;
|
||||
- gid_t gid = set_group_flag ? set_group : file_hdr->c_gid;
|
||||
- if ((lchown (file_hdr->c_name, uid, gid) < 0)
|
||||
- && errno != EPERM)
|
||||
- chown_error_details (file_hdr->c_name, uid, gid);
|
||||
+ res = UMASKED_SYMLINK (link_name, file_hdr->c_name,
|
||||
+ file_hdr->c_mode);
|
||||
+ if (res < 0 && create_dir_flag)
|
||||
+ {
|
||||
+ create_all_directories (file_hdr->c_name);
|
||||
+ res = UMASKED_SYMLINK (link_name, file_hdr->c_name, file_hdr->c_mode);
|
||||
+ }
|
||||
+ if (res < 0)
|
||||
+ symlink_error (link_name, file_hdr->c_name);
|
||||
+ else if (!no_chown_flag)
|
||||
+ {
|
||||
+ uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid;
|
||||
+ gid_t gid = set_group_flag ? set_group : file_hdr->c_gid;
|
||||
+ if (lchown (file_hdr->c_name, uid, gid) < 0 && errno != EPERM)
|
||||
+ chown_error_details (file_hdr->c_name, uid, gid);
|
||||
+ }
|
||||
}
|
||||
free (link_name);
|
||||
}
|
||||
@@ -1425,6 +1553,7 @@ process_copy_in (void)
|
||||
if (dot_flag)
|
||||
fputc ('\n', stderr);
|
||||
|
||||
+ replace_symlink_placeholders ();
|
||||
apply_delayed_set_stat ();
|
||||
|
||||
cpio_file_stat_free (&file_hdr);
|
||||
diff --git a/tests/CVE-2015-1197.at b/tests/CVE-2015-1197.at
|
||||
index 57ebe43..74591b1 100644
|
||||
--- a/tests/CVE-2015-1197.at
|
||||
+++ b/tests/CVE-2015-1197.at
|
||||
@@ -24,18 +24,15 @@ AT_DATA([filelist],
|
||||
[dir
|
||||
dir/file
|
||||
])
|
||||
-ln -s /tmp dir
|
||||
-touch /tmp/file
|
||||
cpio -o < filelist > test.cpio
|
||||
-rm dir /tmp/file
|
||||
+rm -rf dir $tempdir
|
||||
cpio --no-absolute-filenames -iv < test.cpio
|
||||
],
|
||||
[2],
|
||||
[],
|
||||
[1 block
|
||||
-cpio: Removing leading `/' from hard link targets
|
||||
dir
|
||||
-cpio: dir/file: Cannot open: No such file or directory
|
||||
+cpio: dir/file: Cannot open: Not a directory
|
||||
dir/file
|
||||
1 block
|
||||
])
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
From 388fbb65a2d7244717aaeac2b316b51ee0474dd4 Mon Sep 17 00:00:00 2001
|
||||
From: Ziyang Chen <chenziyang4@huawei.com>
|
||||
Date: Mon, 10 Jul 2023 20:19:27 +0800
|
||||
Subject: [PATCH] Do not set exit code to 2 when failing to create symlink
|
||||
|
||||
Reference:https://lists.gnu.org/archive/html/bug-cpio/2023-07/msg00001.html
|
||||
Conflict:NA
|
||||
---
|
||||
src/copyin.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/copyin.c b/src/copyin.c
|
||||
index dc715ff..6fa5699 100644
|
||||
--- a/src/copyin.c
|
||||
+++ b/src/copyin.c
|
||||
@@ -742,7 +742,7 @@ replace_symlink_placeholders (void)
|
||||
res = UMASKED_SYMLINK (dl->source, dl->target, dl->mode);
|
||||
}
|
||||
if (res < 0)
|
||||
- symlink_error (dl->source, dl->target);
|
||||
+ error (0, errno, _("%s: Cannot create symlink to %s"), quotearg_colon (dl->target), quote_n (1, dl->source));
|
||||
else if (!no_chown_flag)
|
||||
{
|
||||
uid_t uid = set_owner_flag ? set_owner : dl->uid;
|
||||
@@ -795,7 +795,7 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des)
|
||||
res = UMASKED_SYMLINK (link_name, file_hdr->c_name, file_hdr->c_mode);
|
||||
}
|
||||
if (res < 0)
|
||||
- symlink_error (link_name, file_hdr->c_name);
|
||||
+ error (0, errno, _("%s: Cannot create symlink to %s"), quotearg_colon (file_hdr->c_name), quote_n (1, link_name));
|
||||
else if (!no_chown_flag)
|
||||
{
|
||||
uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid;
|
||||
--
|
||||
2.33.0
|
||||
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
From 06789cf2a6a0121f75fada35926f09ec851a609f Mon Sep 17 00:00:00 2001
|
||||
From: Sergey Poznyakoff <gray@gnu.org>
|
||||
Date: Thu, 18 May 2023 09:00:12 +0300
|
||||
Subject: [PATCH] Fix operation of --no-absolute-filenames --make-directories
|
||||
|
||||
* src/copyin.c (symlink_placeholder): Try to create leading
|
||||
directories if unable to create placeholder.
|
||||
|
||||
Reference:http://git.savannah.gnu.org/cgit/cpio.git/commit/?id=e3cc782c610729de7622a274e532817c18262a9d
|
||||
Conflict:NA
|
||||
---
|
||||
src/copyin.c | 6 ++++++
|
||||
2 files changed, 20 insertions(+)
|
||||
create mode 100644 src/copyin.c.rej
|
||||
|
||||
diff --git a/src/copyin.c b/src/copyin.c
|
||||
index 69d4ca4..53a84e5 100644
|
||||
--- a/src/copyin.c
|
||||
+++ b/src/copyin.c
|
||||
@@ -668,6 +668,12 @@ symlink_placeholder (char *oldpath, char *newpath, struct cpio_file_stat *file_s
|
||||
struct delayed_link *p;
|
||||
size_t newlen = strlen (newpath);
|
||||
|
||||
+ if (fd < 0 && create_dir_flag)
|
||||
+ {
|
||||
+ create_all_directories (newpath);
|
||||
+ fd = open (newpath, O_WRONLY | O_CREAT | O_EXCL, 0);
|
||||
+ }
|
||||
+
|
||||
if (fd < 0)
|
||||
{
|
||||
open_error (newpath);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
14
cpio.spec
14
cpio.spec
@ -1,6 +1,6 @@
|
||||
Name: cpio
|
||||
Version: 2.13
|
||||
Release: 6
|
||||
Release: 7
|
||||
Summary: A GNU archiving program
|
||||
|
||||
License: GPLv3+
|
||||
@ -14,10 +14,12 @@ Patch3: cpio-2.9.90-defaultremoteshell.patch
|
||||
Patch4: cpio-2.10-patternnamesigsegv.patch
|
||||
Patch5: cpio-2.10-longnames-split.patch
|
||||
Patch6: cpio-2.11-crc-fips-nit.patch
|
||||
Patch7: revert-CVE-2015-1197.patch
|
||||
Patch8: backport-0001-CVE-2021-38185-Rewrite-dynamic-string-support.patch
|
||||
Patch9: backport-0002-CVE-2021-38185-Fix-previous-commit.patch
|
||||
Patch10: backport-0003-CVE-2021-38185-Fix-dynamic-string-reallocations.patch
|
||||
Patch11: backport-CVE-2015-1197.patch
|
||||
Patch12: backport-fix-operation-of-no-absolute-filenames-make-director.patch
|
||||
Patch13: backport-Do-not-set-exit-code-to-2-when-failing-to-create-sym.patch
|
||||
|
||||
Patch9000: add-option-to-add-metadata-in-copy-out-mode.patch
|
||||
Patch9001: Fix-use-after-free-and-return-appropriate-error.patch
|
||||
@ -63,6 +65,14 @@ make check
|
||||
%{_datadir}/man/man1/%{name}.1.gz
|
||||
|
||||
%changelog
|
||||
* Mon Sep 11 2023 chenziyang <chenziyang4@huawei.com> - 2.13-7
|
||||
- Type:CVE
|
||||
- ID:CVE-2015-1197
|
||||
- SUG:NA
|
||||
- DESC:Fix CVE-2015-1197, delete revert-CVE-2015-1197.patch because new patch
|
||||
will fix the problem brought by old-CVE-2015-1197.patch, so we delete
|
||||
revert-CVE-2015-1197.patch
|
||||
|
||||
* Tue Jun 20 2023 fuanan <fuanan3@h-partners.com> - 2.13-6
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
|
||||
@ -1,109 +0,0 @@
|
||||
From 250cae97153b438f5644e5d96814a7f5cb8c80e5 Mon Sep 17 00:00:00 2001
|
||||
From: Liquor <lirui130@huawei.com>
|
||||
Date: Thu, 26 Nov 2020 19:13:13 +0800
|
||||
Subject: [PATCH] revert "CVE-2015-1197"
|
||||
|
||||
reason:https://lists.gnu.org/archive/html/bug-cpio/2019-11/msg00016.html
|
||||
---
|
||||
src/copyin.c | 5 ++---
|
||||
tests/CVE-2015-1197.at | 43 ------------------------------------------
|
||||
tests/Makefile.am | 1 -
|
||||
tests/testsuite.at | 1 -
|
||||
4 files changed, 2 insertions(+), 48 deletions(-)
|
||||
delete mode 100644 tests/CVE-2015-1197.at
|
||||
|
||||
diff --git a/src/copyin.c b/src/copyin.c
|
||||
index de31636..bf3b0a8 100644
|
||||
--- a/src/copyin.c
|
||||
+++ b/src/copyin.c
|
||||
@@ -645,14 +645,13 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des)
|
||||
link_name = xstrdup (file_hdr->c_tar_linkname);
|
||||
}
|
||||
|
||||
- cpio_safer_name_suffix (link_name, true, !no_abs_paths_flag, false);
|
||||
-
|
||||
res = UMASKED_SYMLINK (link_name, file_hdr->c_name,
|
||||
file_hdr->c_mode);
|
||||
if (res < 0 && create_dir_flag)
|
||||
{
|
||||
create_all_directories (file_hdr->c_name);
|
||||
- res = UMASKED_SYMLINK (link_name, file_hdr->c_name, file_hdr->c_mode);
|
||||
+ res = UMASKED_SYMLINK (link_name, file_hdr->c_name,
|
||||
+ file_hdr->c_mode);
|
||||
}
|
||||
if (res < 0)
|
||||
{
|
||||
diff --git a/tests/CVE-2015-1197.at b/tests/CVE-2015-1197.at
|
||||
deleted file mode 100644
|
||||
index 6079af7..0000000
|
||||
--- a/tests/CVE-2015-1197.at
|
||||
+++ /dev/null
|
||||
@@ -1,43 +0,0 @@
|
||||
-# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
-# Copyright (C) 2009-2019 Free Software Foundation, Inc.
|
||||
-#
|
||||
-# This program is free software; you can redistribute it and/or modify
|
||||
-# it under the terms of the GNU General Public License as published by
|
||||
-# the Free Software Foundation; either version 3, or (at your option)
|
||||
-# any later version.
|
||||
-#
|
||||
-# This program is distributed in the hope that it will be useful,
|
||||
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-# GNU General Public License for more details.
|
||||
-#
|
||||
-# You should have received a copy of the GNU General Public License
|
||||
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-AT_SETUP([CVE-2015-1197 (--no-absolute-filenames for symlinks)])
|
||||
-AT_CHECK([
|
||||
-tempdir=$(pwd)/tmp
|
||||
-mkdir $tempdir
|
||||
-touch $tempdir/file
|
||||
-ln -s $tempdir dir
|
||||
-AT_DATA([filelist],
|
||||
-[dir
|
||||
-dir/file
|
||||
-])
|
||||
-ln -s /tmp dir
|
||||
-touch /tmp/file
|
||||
-cpio -o < filelist > test.cpio
|
||||
-rm dir /tmp/file
|
||||
-cpio --no-absolute-filenames -iv < test.cpio
|
||||
-],
|
||||
-[2],
|
||||
-[],
|
||||
-[1 block
|
||||
-cpio: Removing leading `/' from hard link targets
|
||||
-dir
|
||||
-cpio: dir/file: Cannot open: No such file or directory
|
||||
-dir/file
|
||||
-1 block
|
||||
-])
|
||||
-AT_CLEANUP
|
||||
-
|
||||
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||
index 65bf470..a71c057 100644
|
||||
--- a/tests/Makefile.am
|
||||
+++ b/tests/Makefile.am
|
||||
@@ -56,7 +56,6 @@ TESTSUITE_AT = \
|
||||
symlink-to-stdout.at\
|
||||
version.at\
|
||||
big-block-size.at\
|
||||
- CVE-2015-1197.at\
|
||||
CVE-2019-14866.at
|
||||
|
||||
TESTSUITE = $(srcdir)/testsuite
|
||||
diff --git a/tests/testsuite.at b/tests/testsuite.at
|
||||
index aa56bb9..58ed1d2 100644
|
||||
--- a/tests/testsuite.at
|
||||
+++ b/tests/testsuite.at
|
||||
@@ -44,5 +44,4 @@ m4_include([setstat04.at])
|
||||
m4_include([setstat05.at])
|
||||
m4_include([big-block-size.at])
|
||||
|
||||
-m4_include([CVE-2015-1197.at])
|
||||
m4_include([CVE-2019-14866.at])
|
||||
--
|
||||
2.27.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user