Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)

libarchive: fix CVE-2015-1197 by upstream patch

Fixes #6799.

+144
+143
pkgs/development/libraries/libarchive/CVE-2015-1197.patch
···
··· 1 + From 59357157706d47c365b2227739e17daba3607526 Mon Sep 17 00:00:00 2001 2 + From: Alessandro Ghedini <alessandro@ghedini.me> 3 + Date: Sun, 1 Mar 2015 12:07:45 +0100 4 + Subject: [PATCH] Add ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS option 5 + 6 + This fixes a directory traversal in the cpio tool. 7 + --- 8 + cpio/bsdcpio.1 | 3 ++- 9 + cpio/cpio.c | 2 ++ 10 + libarchive/archive.h | 2 ++ 11 + libarchive/archive_write_disk.3 | 3 +++ 12 + libarchive/archive_write_disk_posix.c | 14 +++++++++++--- 13 + libarchive/test/test_write_disk_secure.c | 23 +++++++++++++++++++++++ 14 + 6 files changed, 43 insertions(+), 4 deletions(-) 15 + 16 + diff --git a/cpio/bsdcpio.1 b/cpio/bsdcpio.1 17 + index f966aa0..e52546e 100644 18 + --- a/cpio/bsdcpio.1 19 + +++ b/cpio/bsdcpio.1 20 + @@ -156,7 +156,8 @@ See above for description. 21 + .It Fl Fl insecure 22 + (i and p mode only) 23 + Disable security checks during extraction or copying. 24 + -This allows extraction via symbolic links and path names containing 25 + +This allows extraction via symbolic links, absolute paths, 26 + +and path names containing 27 + .Sq .. 28 + in the name. 29 + .It Fl J , Fl Fl xz 30 + diff --git a/cpio/cpio.c b/cpio/cpio.c 31 + index 0acde11..b267e9b 100644 32 + --- a/cpio/cpio.c 33 + +++ b/cpio/cpio.c 34 + @@ -171,6 +171,7 @@ main(int argc, char *argv[]) 35 + cpio->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER; 36 + cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS; 37 + cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT; 38 + + cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS; 39 + cpio->extract_flags |= ARCHIVE_EXTRACT_PERM; 40 + cpio->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; 41 + cpio->extract_flags |= ARCHIVE_EXTRACT_ACL; 42 + @@ -256,6 +257,7 @@ main(int argc, char *argv[]) 43 + case OPTION_INSECURE: 44 + cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS; 45 + cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT; 46 + + cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS; 47 + break; 48 + case 'L': /* GNU cpio */ 49 + cpio->option_follow_links = 1; 50 + diff --git a/libarchive/archive.h b/libarchive/archive.h 51 + index 1f0fc38..ef635ac 100644 52 + --- a/libarchive/archive.h 53 + +++ b/libarchive/archive.h 54 + @@ -649,6 +649,8 @@ __LA_DECL int archive_read_set_passphrase_callback(struct archive *, 55 + /* Default: Do not use HFS+ compression if it was not compressed. */ 56 + /* This has no effect except on Mac OS v10.6 or later. */ 57 + #define ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED (0x8000) 58 + +/* Default: Do not reject entries with absolute paths */ 59 + +#define ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS (0x10000) 60 + 61 + __LA_DECL int archive_read_extract(struct archive *, struct archive_entry *, 62 + int flags); 63 + diff --git a/libarchive/archive_write_disk.3 b/libarchive/archive_write_disk.3 64 + index fa925cc..a2e7afa 100644 65 + --- a/libarchive/archive_write_disk.3 66 + +++ b/libarchive/archive_write_disk.3 67 + @@ -177,6 +177,9 @@ The default is to not refuse such paths. 68 + Note that paths ending in 69 + .Pa .. 70 + always cause an error, regardless of this flag. 71 + +.It Cm ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS 72 + +Refuse to extract an absolute path. 73 + +The default is to not refuse such paths. 74 + .It Cm ARCHIVE_EXTRACT_SPARSE 75 + Scan data for blocks of NUL bytes and try to recreate them with holes. 76 + This results in sparse files, independent of whether the archive format 77 + diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c 78 + index ab3bdac..c1290eb 100644 79 + --- a/libarchive/archive_write_disk_posix.c 80 + +++ b/libarchive/archive_write_disk_posix.c 81 + @@ -2509,8 +2509,9 @@ cleanup_pathname_win(struct archive_write_disk *a) 82 + /* 83 + * Canonicalize the pathname. In particular, this strips duplicate 84 + * '/' characters, '.' elements, and trailing '/'. It also raises an 85 + - * error for an empty path, a trailing '..' or (if _SECURE_NODOTDOT is 86 + - * set) any '..' in the path. 87 + + * error for an empty path, a trailing '..', (if _SECURE_NODOTDOT is 88 + + * set) any '..' in the path or (if ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS 89 + + * is set) if the path is absolute. 90 + */ 91 + static int 92 + cleanup_pathname(struct archive_write_disk *a) 93 + @@ -2529,8 +2530,15 @@ cleanup_pathname(struct archive_write_disk *a) 94 + cleanup_pathname_win(a); 95 + #endif 96 + /* Skip leading '/'. */ 97 + - if (*src == '/') 98 + + if (*src == '/') { 99 + + if (a->flags & ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS) { 100 + + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 101 + + "Path is absolute"); 102 + + return (ARCHIVE_FAILED); 103 + + } 104 + + 105 + separator = *src++; 106 + + } 107 + 108 + /* Scan the pathname one element at a time. */ 109 + for (;;) { 110 + diff --git a/libarchive/test/test_write_disk_secure.c b/libarchive/test/test_write_disk_secure.c 111 + index 31c5bfd..2c94206 100644 112 + --- a/libarchive/test/test_write_disk_secure.c 113 + +++ b/libarchive/test/test_write_disk_secure.c 114 + @@ -178,6 +178,29 @@ DEFINE_TEST(test_write_disk_secure) 115 + assert(S_ISDIR(st.st_mode)); 116 + archive_entry_free(ae); 117 + 118 + + /* 119 + + * Without security checks, we should be able to 120 + + * extract an absolute path. 121 + + */ 122 + + assert((ae = archive_entry_new()) != NULL); 123 + + archive_entry_copy_pathname(ae, "/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp"); 124 + + archive_entry_set_mode(ae, S_IFREG | 0777); 125 + + assert(0 == archive_write_header(a, ae)); 126 + + assert(0 == archive_write_finish_entry(a)); 127 + + assertFileExists("/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp"); 128 + + assert(0 == unlink("/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp")); 129 + + 130 + + /* But with security checks enabled, this should fail. */ 131 + + assert(archive_entry_clear(ae) != NULL); 132 + + archive_entry_copy_pathname(ae, "/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp"); 133 + + archive_entry_set_mode(ae, S_IFREG | 0777); 134 + + archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS); 135 + + failure("Extracting an absolute path should fail here."); 136 + + assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); 137 + + archive_entry_free(ae); 138 + + assert(0 == archive_write_finish_entry(a)); 139 + + assertFileNotExists("/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp"); 140 + + 141 + assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 142 + 143 + /* Test the entries on disk. */
+1
pkgs/development/libraries/libarchive/default.nix
··· 14 15 patches = [ 16 ./CVE-2013-0211.patch # https://github.com/libarchive/libarchive/commit/22531545 17 ]; 18 19 buildInputs = [ sharutils libxml2 zlib bzip2 openssl xz ] ++
··· 14 15 patches = [ 16 ./CVE-2013-0211.patch # https://github.com/libarchive/libarchive/commit/22531545 17 + ./CVE-2015-1197.patch # https://github.com/NixOS/nixpkgs/issues/6799 18 ]; 19 20 buildInputs = [ sharutils libxml2 zlib bzip2 openssl xz ] ++