revert fix CVE-2015-1197 because it causes AT testcases problems
This commit is contained in:
parent
d6e41ec0c1
commit
a2a43267f5
@ -1,273 +0,0 @@
|
|||||||
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: [PATCH] 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.
|
|
||||||
---
|
|
||||||
src/copyin.c | 172 +++++++++++++++++++++++++++++++++++------
|
|
||||||
tests/CVE-2015-1197.at | 40 +++++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 192 insertions(+), 20 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,28 +776,26 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des)
|
|
||||||
link_name = xstrdup (file_hdr->c_tar_linkname);
|
|
||||||
}
|
|
||||||
|
|
||||||
- res = UMASKED_SYMLINK (link_name, file_hdr->c_name,
|
|
||||||
- file_hdr->c_mode);
|
|
||||||
- if (res < 0 && create_dir_flag)
|
|
||||||
+ if (no_abs_paths_flag)
|
|
||||||
+ symlink_placeholder (link_name, file_hdr->c_name, file_hdr);
|
|
||||||
+ else
|
|
||||||
{
|
|
||||||
- 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)
|
|
||||||
- {
|
|
||||||
- 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);
|
|
||||||
+ 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
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..6079af7
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/tests/CVE-2015-1197.at
|
|
||||||
@@ -0,0 +1,40 @@
|
|
||||||
+# 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
|
|
||||||
+])
|
|
||||||
+cpio -o < filelist > test.cpio
|
|
||||||
+rm -rf dir $tempdir
|
|
||||||
+cpio --no-absolute-filenames -iv < test.cpio
|
|
||||||
+],
|
|
||||||
+[2],
|
|
||||||
+[],
|
|
||||||
+[1 block
|
|
||||||
+dir
|
|
||||||
+cpio: dir/file: Cannot open: Not a directory
|
|
||||||
+dir/file
|
|
||||||
+1 block
|
|
||||||
+])
|
|
||||||
+AT_CLEANUP
|
|
||||||
+
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
Name: cpio
|
Name: cpio
|
||||||
Version: 2.13
|
Version: 2.13
|
||||||
Release: 8
|
Release: 9
|
||||||
Summary: A GNU archiving program
|
Summary: A GNU archiving program
|
||||||
|
|
||||||
License: GPLv3+
|
License: GPLv3+
|
||||||
@ -19,7 +19,6 @@ Patch8: backport-cpio-2.13-mutiple-definition.patch
|
|||||||
Patch9: backport-0001-CVE-2021-38185-Rewrite-dynamic-string-support.patch
|
Patch9: backport-0001-CVE-2021-38185-Rewrite-dynamic-string-support.patch
|
||||||
Patch10: backport-0002-CVE-2021-38185-Fix-previous-commit.patch
|
Patch10: backport-0002-CVE-2021-38185-Fix-previous-commit.patch
|
||||||
Patch11: backport-0003-CVE-2021-38185-Fix-dynamic-string-reallocations.patch
|
Patch11: backport-0003-CVE-2021-38185-Fix-dynamic-string-reallocations.patch
|
||||||
Patch12: backport-CVE-2015-1197-Fix-45b0ee2b407913c533f7ded8d6f8cbeec16ff6ca.patch
|
|
||||||
|
|
||||||
Patch9000: add-option-to-add-metadata-in-copy-out-mode.patch
|
Patch9000: add-option-to-add-metadata-in-copy-out-mode.patch
|
||||||
Patch9001: Fix-use-after-free-and-return-appropriate-error.patch
|
Patch9001: Fix-use-after-free-and-return-appropriate-error.patch
|
||||||
@ -65,6 +64,12 @@ make check
|
|||||||
%{_datadir}/man/man1/%{name}.1.gz
|
%{_datadir}/man/man1/%{name}.1.gz
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jun 20 2023 fuanan <fuanan3@h-partners.com> - 2.13-9
|
||||||
|
- Type:bugfix
|
||||||
|
- ID:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:revert fix CVE-2015-1197 because it causes AT testcases problems
|
||||||
|
|
||||||
* Sat May 27 2023 fuanan <fuanan3@h-partners.com> - 2.13-8
|
* Sat May 27 2023 fuanan <fuanan3@h-partners.com> - 2.13-8
|
||||||
- Type:CVE
|
- Type:CVE
|
||||||
- ID:CVE-2015-1197
|
- ID:CVE-2015-1197
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user