aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended/libarchive/files/0002-Fix-extracting-hardlinks-over-symlinks.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-extended/libarchive/files/0002-Fix-extracting-hardlinks-over-symlinks.patch')
-rw-r--r--meta/recipes-extended/libarchive/files/0002-Fix-extracting-hardlinks-over-symlinks.patch120
1 files changed, 120 insertions, 0 deletions
diff --git a/meta/recipes-extended/libarchive/files/0002-Fix-extracting-hardlinks-over-symlinks.patch b/meta/recipes-extended/libarchive/files/0002-Fix-extracting-hardlinks-over-symlinks.patch
new file mode 100644
index 00000000000..37418632f35
--- /dev/null
+++ b/meta/recipes-extended/libarchive/files/0002-Fix-extracting-hardlinks-over-symlinks.patch
@@ -0,0 +1,120 @@
+From ece28103885a079a129a23c5001252a1648517af Mon Sep 17 00:00:00 2001
+From: Martin Matuska <martin@matuska.org>
+Date: Tue, 29 Nov 2016 16:55:41 +0100
+Subject: [PATCH 2/2] Fix extracting hardlinks over symlinks
+
+Closes #821
+
+Upstream-Status: Backported
+
+Signed-off-by: Amarnath Valluri <amarnath.valluri@intel.com>
+---
+ libarchive/archive_write_disk_posix.c | 43 +++++++++++++++++++++++++++++++++++
+ tar/test/test_symlink_dir.c | 18 ++++++++++++++-
+ 2 files changed, 60 insertions(+), 1 deletion(-)
+
+diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
+index d786bc2..80b03cd 100644
+--- a/libarchive/archive_write_disk_posix.c
++++ b/libarchive/archive_write_disk_posix.c
+@@ -2563,6 +2563,49 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr, int
+ break;
+ }
+ tail[0] = c;
++ } else if ((flags &
++ ARCHIVE_EXTRACT_SECURE_SYMLINKS) == 0) {
++ /*
++ * We are not the last element and we want to
++ * follow symlinks if they are a directory.
++ *
++ * This is needed to extract hardlinks over
++ * symlinks.
++ */
++ r = stat(head, &st);
++ if (r != 0) {
++ tail[0] = c;
++ if (errno == ENOENT) {
++ break;
++ } else {
++ fsobj_error(a_eno, a_estr,
++ errno,
++ "Could not stat %s", path);
++ res = (ARCHIVE_FAILED);
++ break;
++ }
++ } else if (S_ISDIR(st.st_mode)) {
++ if (chdir(head) != 0) {
++ tail[0] = c;
++ fsobj_error(a_eno, a_estr,
++ errno,
++ "Could not chdir %s", path);
++ res = (ARCHIVE_FATAL);
++ break;
++ }
++ /*
++ * Our view is now from inside
++ * this dir:
++ */
++ head = tail + 1;
++ } else {
++ tail[0] = c;
++ fsobj_error(a_eno, a_estr, 0,
++ "Cannot extract through "
++ "symlink %s", path);
++ res = ARCHIVE_FAILED;
++ break;
++ }
+ } else {
+ tail[0] = c;
+ fsobj_error(a_eno, a_estr, 0,
+diff --git a/tar/test/test_symlink_dir.c b/tar/test/test_symlink_dir.c
+index 25bd8b1..852e00b 100644
+--- a/tar/test/test_symlink_dir.c
++++ b/tar/test/test_symlink_dir.c
+@@ -47,11 +47,18 @@ DEFINE_TEST(test_symlink_dir)
+ assertMakeDir("source/dir3", 0755);
+ assertMakeDir("source/dir3/d3", 0755);
+ assertMakeFile("source/dir3/f3", 0755, "abcde");
++ assertMakeDir("source/dir4", 0755);
++ assertMakeFile("source/dir4/file3", 0755, "abcdef");
++ assertMakeHardlink("source/dir4/file4", "source/dir4/file3");
+
+ assertEqualInt(0,
+ systemf("%s -cf test.tar -C source dir dir2 dir3 file file2",
+ testprog));
+
++ /* Second archive with hardlinks */
++ assertEqualInt(0,
++ systemf("%s -cf test2.tar -C source dir4", testprog));
++
+ /*
+ * Extract with -x and without -P.
+ */
+@@ -118,9 +125,15 @@ DEFINE_TEST(test_symlink_dir)
+ assertMakeSymlink("dest2/file2", "real_file2");
+ assertEqualInt(0, systemf("%s -xPf test.tar -C dest2", testprog));
+
+- /* dest2/dir symlink should be followed */
++ /* "dir4" is a symlink to existing "real_dir" */
++ if (canSymlink())
++ assertMakeSymlink("dest2/dir4", "real_dir");
++ assertEqualInt(0, systemf("%s -xPf test2.tar -C dest2", testprog));
++
++ /* dest2/dir and dest2/dir4 symlinks should be followed */
+ if (canSymlink()) {
+ assertIsSymlink("dest2/dir", "real_dir");
++ assertIsSymlink("dest2/dir4", "real_dir");
+ assertIsDir("dest2/real_dir", -1);
+ }
+
+@@ -141,4 +154,7 @@ DEFINE_TEST(test_symlink_dir)
+ /* dest2/file2 symlink should be removed */
+ failure("Symlink to non-existing file should be removed");
+ assertIsReg("dest2/file2", -1);
++
++ /* dest2/dir4/file3 and dest2/dir4/file4 should be hard links */
++ assertIsHardlink("dest2/dir4/file3", "dest2/dir4/file4");
+ }
+--
+2.7.4
+