diff options
Diffstat (limited to 'meta/recipes-extended/libarchive')
3 files changed, 367 insertions, 0 deletions
diff --git a/meta/recipes-extended/libarchive/files/0001-archive_write_disk_posix.c-make-_fsobj-functions-mor.patch b/meta/recipes-extended/libarchive/files/0001-archive_write_disk_posix.c-make-_fsobj-functions-mor.patch new file mode 100644 index 0000000000..e911a7c1f2 --- /dev/null +++ b/meta/recipes-extended/libarchive/files/0001-archive_write_disk_posix.c-make-_fsobj-functions-mor.patch | |||
@@ -0,0 +1,245 @@ | |||
1 | From 90881d24d3f6d5fb207e97df3b91bbea8598e84e Mon Sep 17 00:00:00 2001 | ||
2 | From: Martin Matuska <martin@matuska.org> | ||
3 | Date: Tue, 29 Nov 2016 16:47:37 +0100 | ||
4 | Subject: [PATCH 1/2] archive_write_disk_posix.c: make *_fsobj functions more | ||
5 | readable | ||
6 | |||
7 | Upstream-Status: Backported | ||
8 | |||
9 | Signed-off-by: Amarnath Valluri <amarnath.valluri@intel.com> | ||
10 | --- | ||
11 | libarchive/archive_write_disk_posix.c | 121 +++++++++++++++++----------------- | ||
12 | 1 file changed, 61 insertions(+), 60 deletions(-) | ||
13 | |||
14 | diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c | ||
15 | index 17c23b0..d786bc2 100644 | ||
16 | --- a/libarchive/archive_write_disk_posix.c | ||
17 | +++ b/libarchive/archive_write_disk_posix.c | ||
18 | @@ -336,6 +336,8 @@ struct archive_write_disk { | ||
19 | |||
20 | #define HFS_BLOCKS(s) ((s) >> 12) | ||
21 | |||
22 | +static void fsobj_error(int *, struct archive_string *, int, const char *, | ||
23 | + const char *); | ||
24 | static int check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error_string, int flags); | ||
25 | static int check_symlinks(struct archive_write_disk *); | ||
26 | static int create_filesystem_object(struct archive_write_disk *); | ||
27 | @@ -2005,8 +2007,9 @@ restore_entry(struct archive_write_disk *a) | ||
28 | |||
29 | if (en) { | ||
30 | /* Everything failed; give up here. */ | ||
31 | - archive_set_error(&a->archive, en, "Can't create '%s'", | ||
32 | - a->name); | ||
33 | + if ((&a->archive)->error == NULL) | ||
34 | + archive_set_error(&a->archive, en, "Can't create '%s'", | ||
35 | + a->name); | ||
36 | return (ARCHIVE_FAILED); | ||
37 | } | ||
38 | |||
39 | @@ -2388,6 +2391,17 @@ current_fixup(struct archive_write_disk *a, const char *pathname) | ||
40 | return (a->current_fixup); | ||
41 | } | ||
42 | |||
43 | +/* Error helper for new *_fsobj functions */ | ||
44 | +static void | ||
45 | +fsobj_error(int *a_eno, struct archive_string *a_estr, | ||
46 | + int err, const char *errstr, const char *path) | ||
47 | +{ | ||
48 | + if (a_eno) | ||
49 | + *a_eno = err; | ||
50 | + if (a_estr) | ||
51 | + archive_string_sprintf(a_estr, errstr, path); | ||
52 | +} | ||
53 | + | ||
54 | /* | ||
55 | * TODO: Someday, integrate this with the deep dir support; they both | ||
56 | * scan the path and both can be optimized by comparing against other | ||
57 | @@ -2400,7 +2414,7 @@ current_fixup(struct archive_write_disk *a, const char *pathname) | ||
58 | * ARCHIVE_OK if there are none, otherwise puts an error in errmsg. | ||
59 | */ | ||
60 | static int | ||
61 | -check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error_string, int flags) | ||
62 | +check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr, int flags) | ||
63 | { | ||
64 | #if !defined(HAVE_LSTAT) | ||
65 | /* Platform doesn't have lstat, so we can't look for symlinks. */ | ||
66 | @@ -2474,19 +2488,20 @@ check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error | ||
67 | if (errno == ENOENT) { | ||
68 | break; | ||
69 | } else { | ||
70 | - /* Treat any other error as fatal - best to be paranoid here | ||
71 | - * Note: This effectively disables deep directory | ||
72 | - * support when security checks are enabled. | ||
73 | - * Otherwise, very long pathnames that trigger | ||
74 | - * an error here could evade the sandbox. | ||
75 | - * TODO: We could do better, but it would probably | ||
76 | - * require merging the symlink checks with the | ||
77 | - * deep-directory editing. */ | ||
78 | - if (error_number) *error_number = errno; | ||
79 | - if (error_string) | ||
80 | - archive_string_sprintf(error_string, | ||
81 | - "Could not stat %s", | ||
82 | - path); | ||
83 | + /* | ||
84 | + * Treat any other error as fatal - best to be | ||
85 | + * paranoid here. | ||
86 | + * Note: This effectively disables deep | ||
87 | + * directory support when security checks are | ||
88 | + * enabled. Otherwise, very long pathnames that | ||
89 | + * trigger an error here could evade the | ||
90 | + * sandbox. | ||
91 | + * TODO: We could do better, but it would | ||
92 | + * probably require merging the symlink checks | ||
93 | + * with the deep-directory editing. | ||
94 | + */ | ||
95 | + fsobj_error(a_eno, a_estr, errno, | ||
96 | + "Could not stat %s", path); | ||
97 | res = ARCHIVE_FAILED; | ||
98 | break; | ||
99 | } | ||
100 | @@ -2494,11 +2509,8 @@ check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error | ||
101 | if (!last) { | ||
102 | if (chdir(head) != 0) { | ||
103 | tail[0] = c; | ||
104 | - if (error_number) *error_number = errno; | ||
105 | - if (error_string) | ||
106 | - archive_string_sprintf(error_string, | ||
107 | - "Could not chdir %s", | ||
108 | - path); | ||
109 | + fsobj_error(a_eno, a_estr, errno, | ||
110 | + "Could not chdir %s", path); | ||
111 | res = (ARCHIVE_FATAL); | ||
112 | break; | ||
113 | } | ||
114 | @@ -2514,11 +2526,9 @@ check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error | ||
115 | */ | ||
116 | if (unlink(head)) { | ||
117 | tail[0] = c; | ||
118 | - if (error_number) *error_number = errno; | ||
119 | - if (error_string) | ||
120 | - archive_string_sprintf(error_string, | ||
121 | - "Could not remove symlink %s", | ||
122 | - path); | ||
123 | + fsobj_error(a_eno, a_estr, errno, | ||
124 | + "Could not remove symlink %s", | ||
125 | + path); | ||
126 | res = ARCHIVE_FAILED; | ||
127 | break; | ||
128 | } | ||
129 | @@ -2529,13 +2539,14 @@ check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error | ||
130 | * symlink with another symlink. | ||
131 | */ | ||
132 | tail[0] = c; | ||
133 | - /* FIXME: not sure how important this is to restore | ||
134 | + /* | ||
135 | + * FIXME: not sure how important this is to | ||
136 | + * restore | ||
137 | + */ | ||
138 | + /* | ||
139 | if (!S_ISLNK(path)) { | ||
140 | - if (error_number) *error_number = 0; | ||
141 | - if (error_string) | ||
142 | - archive_string_sprintf(error_string, | ||
143 | - "Removing symlink %s", | ||
144 | - path); | ||
145 | + fsobj_error(a_eno, a_estr, 0, | ||
146 | + "Removing symlink %s", path); | ||
147 | } | ||
148 | */ | ||
149 | /* Symlink gone. No more problem! */ | ||
150 | @@ -2545,22 +2556,17 @@ check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error | ||
151 | /* User asked us to remove problems. */ | ||
152 | if (unlink(head) != 0) { | ||
153 | tail[0] = c; | ||
154 | - if (error_number) *error_number = 0; | ||
155 | - if (error_string) | ||
156 | - archive_string_sprintf(error_string, | ||
157 | - "Cannot remove intervening symlink %s", | ||
158 | - path); | ||
159 | + fsobj_error(a_eno, a_estr, 0, | ||
160 | + "Cannot remove intervening " | ||
161 | + "symlink %s", path); | ||
162 | res = ARCHIVE_FAILED; | ||
163 | break; | ||
164 | } | ||
165 | tail[0] = c; | ||
166 | } else { | ||
167 | tail[0] = c; | ||
168 | - if (error_number) *error_number = 0; | ||
169 | - if (error_string) | ||
170 | - archive_string_sprintf(error_string, | ||
171 | - "Cannot extract through symlink %s", | ||
172 | - path); | ||
173 | + fsobj_error(a_eno, a_estr, 0, | ||
174 | + "Cannot extract through symlink %s", path); | ||
175 | res = ARCHIVE_FAILED; | ||
176 | break; | ||
177 | } | ||
178 | @@ -2577,10 +2583,8 @@ check_symlinks_fsobj(char *path, int *error_number, struct archive_string *error | ||
179 | if (restore_pwd >= 0) { | ||
180 | r = fchdir(restore_pwd); | ||
181 | if (r != 0) { | ||
182 | - if(error_number) *error_number = errno; | ||
183 | - if(error_string) | ||
184 | - archive_string_sprintf(error_string, | ||
185 | - "chdir() failure"); | ||
186 | + fsobj_error(a_eno, a_estr, errno, | ||
187 | + "chdir() failure", ""); | ||
188 | } | ||
189 | close(restore_pwd); | ||
190 | restore_pwd = -1; | ||
191 | @@ -2688,17 +2692,16 @@ cleanup_pathname_win(struct archive_write_disk *a) | ||
192 | * is set) if the path is absolute. | ||
193 | */ | ||
194 | static int | ||
195 | -cleanup_pathname_fsobj(char *path, int *error_number, struct archive_string *error_string, int flags) | ||
196 | +cleanup_pathname_fsobj(char *path, int *a_eno, struct archive_string *a_estr, | ||
197 | + int flags) | ||
198 | { | ||
199 | char *dest, *src; | ||
200 | char separator = '\0'; | ||
201 | |||
202 | dest = src = path; | ||
203 | if (*src == '\0') { | ||
204 | - if (error_number) *error_number = ARCHIVE_ERRNO_MISC; | ||
205 | - if (error_string) | ||
206 | - archive_string_sprintf(error_string, | ||
207 | - "Invalid empty pathname"); | ||
208 | + fsobj_error(a_eno, a_estr, ARCHIVE_ERRNO_MISC, | ||
209 | + "Invalid empty ", "pathname"); | ||
210 | return (ARCHIVE_FAILED); | ||
211 | } | ||
212 | |||
213 | @@ -2708,10 +2711,8 @@ cleanup_pathname_fsobj(char *path, int *error_number, struct archive_string *err | ||
214 | /* Skip leading '/'. */ | ||
215 | if (*src == '/') { | ||
216 | if (flags & ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS) { | ||
217 | - if (error_number) *error_number = ARCHIVE_ERRNO_MISC; | ||
218 | - if (error_string) | ||
219 | - archive_string_sprintf(error_string, | ||
220 | - "Path is absolute"); | ||
221 | + fsobj_error(a_eno, a_estr, ARCHIVE_ERRNO_MISC, | ||
222 | + "Path is ", "absolute"); | ||
223 | return (ARCHIVE_FAILED); | ||
224 | } | ||
225 | |||
226 | @@ -2738,11 +2739,11 @@ cleanup_pathname_fsobj(char *path, int *error_number, struct archive_string *err | ||
227 | } else if (src[1] == '.') { | ||
228 | if (src[2] == '/' || src[2] == '\0') { | ||
229 | /* Conditionally warn about '..' */ | ||
230 | - if (flags & ARCHIVE_EXTRACT_SECURE_NODOTDOT) { | ||
231 | - if (error_number) *error_number = ARCHIVE_ERRNO_MISC; | ||
232 | - if (error_string) | ||
233 | - archive_string_sprintf(error_string, | ||
234 | - "Path contains '..'"); | ||
235 | + if (flags | ||
236 | + & ARCHIVE_EXTRACT_SECURE_NODOTDOT) { | ||
237 | + fsobj_error(a_eno, a_estr, | ||
238 | + ARCHIVE_ERRNO_MISC, | ||
239 | + "Path contains ", "'..'"); | ||
240 | return (ARCHIVE_FAILED); | ||
241 | } | ||
242 | } | ||
243 | -- | ||
244 | 2.7.4 | ||
245 | |||
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 0000000000..37418632f3 --- /dev/null +++ b/meta/recipes-extended/libarchive/files/0002-Fix-extracting-hardlinks-over-symlinks.patch | |||
@@ -0,0 +1,120 @@ | |||
1 | From ece28103885a079a129a23c5001252a1648517af Mon Sep 17 00:00:00 2001 | ||
2 | From: Martin Matuska <martin@matuska.org> | ||
3 | Date: Tue, 29 Nov 2016 16:55:41 +0100 | ||
4 | Subject: [PATCH 2/2] Fix extracting hardlinks over symlinks | ||
5 | |||
6 | Closes #821 | ||
7 | |||
8 | Upstream-Status: Backported | ||
9 | |||
10 | Signed-off-by: Amarnath Valluri <amarnath.valluri@intel.com> | ||
11 | --- | ||
12 | libarchive/archive_write_disk_posix.c | 43 +++++++++++++++++++++++++++++++++++ | ||
13 | tar/test/test_symlink_dir.c | 18 ++++++++++++++- | ||
14 | 2 files changed, 60 insertions(+), 1 deletion(-) | ||
15 | |||
16 | diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c | ||
17 | index d786bc2..80b03cd 100644 | ||
18 | --- a/libarchive/archive_write_disk_posix.c | ||
19 | +++ b/libarchive/archive_write_disk_posix.c | ||
20 | @@ -2563,6 +2563,49 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr, int | ||
21 | break; | ||
22 | } | ||
23 | tail[0] = c; | ||
24 | + } else if ((flags & | ||
25 | + ARCHIVE_EXTRACT_SECURE_SYMLINKS) == 0) { | ||
26 | + /* | ||
27 | + * We are not the last element and we want to | ||
28 | + * follow symlinks if they are a directory. | ||
29 | + * | ||
30 | + * This is needed to extract hardlinks over | ||
31 | + * symlinks. | ||
32 | + */ | ||
33 | + r = stat(head, &st); | ||
34 | + if (r != 0) { | ||
35 | + tail[0] = c; | ||
36 | + if (errno == ENOENT) { | ||
37 | + break; | ||
38 | + } else { | ||
39 | + fsobj_error(a_eno, a_estr, | ||
40 | + errno, | ||
41 | + "Could not stat %s", path); | ||
42 | + res = (ARCHIVE_FAILED); | ||
43 | + break; | ||
44 | + } | ||
45 | + } else if (S_ISDIR(st.st_mode)) { | ||
46 | + if (chdir(head) != 0) { | ||
47 | + tail[0] = c; | ||
48 | + fsobj_error(a_eno, a_estr, | ||
49 | + errno, | ||
50 | + "Could not chdir %s", path); | ||
51 | + res = (ARCHIVE_FATAL); | ||
52 | + break; | ||
53 | + } | ||
54 | + /* | ||
55 | + * Our view is now from inside | ||
56 | + * this dir: | ||
57 | + */ | ||
58 | + head = tail + 1; | ||
59 | + } else { | ||
60 | + tail[0] = c; | ||
61 | + fsobj_error(a_eno, a_estr, 0, | ||
62 | + "Cannot extract through " | ||
63 | + "symlink %s", path); | ||
64 | + res = ARCHIVE_FAILED; | ||
65 | + break; | ||
66 | + } | ||
67 | } else { | ||
68 | tail[0] = c; | ||
69 | fsobj_error(a_eno, a_estr, 0, | ||
70 | diff --git a/tar/test/test_symlink_dir.c b/tar/test/test_symlink_dir.c | ||
71 | index 25bd8b1..852e00b 100644 | ||
72 | --- a/tar/test/test_symlink_dir.c | ||
73 | +++ b/tar/test/test_symlink_dir.c | ||
74 | @@ -47,11 +47,18 @@ DEFINE_TEST(test_symlink_dir) | ||
75 | assertMakeDir("source/dir3", 0755); | ||
76 | assertMakeDir("source/dir3/d3", 0755); | ||
77 | assertMakeFile("source/dir3/f3", 0755, "abcde"); | ||
78 | + assertMakeDir("source/dir4", 0755); | ||
79 | + assertMakeFile("source/dir4/file3", 0755, "abcdef"); | ||
80 | + assertMakeHardlink("source/dir4/file4", "source/dir4/file3"); | ||
81 | |||
82 | assertEqualInt(0, | ||
83 | systemf("%s -cf test.tar -C source dir dir2 dir3 file file2", | ||
84 | testprog)); | ||
85 | |||
86 | + /* Second archive with hardlinks */ | ||
87 | + assertEqualInt(0, | ||
88 | + systemf("%s -cf test2.tar -C source dir4", testprog)); | ||
89 | + | ||
90 | /* | ||
91 | * Extract with -x and without -P. | ||
92 | */ | ||
93 | @@ -118,9 +125,15 @@ DEFINE_TEST(test_symlink_dir) | ||
94 | assertMakeSymlink("dest2/file2", "real_file2"); | ||
95 | assertEqualInt(0, systemf("%s -xPf test.tar -C dest2", testprog)); | ||
96 | |||
97 | - /* dest2/dir symlink should be followed */ | ||
98 | + /* "dir4" is a symlink to existing "real_dir" */ | ||
99 | + if (canSymlink()) | ||
100 | + assertMakeSymlink("dest2/dir4", "real_dir"); | ||
101 | + assertEqualInt(0, systemf("%s -xPf test2.tar -C dest2", testprog)); | ||
102 | + | ||
103 | + /* dest2/dir and dest2/dir4 symlinks should be followed */ | ||
104 | if (canSymlink()) { | ||
105 | assertIsSymlink("dest2/dir", "real_dir"); | ||
106 | + assertIsSymlink("dest2/dir4", "real_dir"); | ||
107 | assertIsDir("dest2/real_dir", -1); | ||
108 | } | ||
109 | |||
110 | @@ -141,4 +154,7 @@ DEFINE_TEST(test_symlink_dir) | ||
111 | /* dest2/file2 symlink should be removed */ | ||
112 | failure("Symlink to non-existing file should be removed"); | ||
113 | assertIsReg("dest2/file2", -1); | ||
114 | + | ||
115 | + /* dest2/dir4/file3 and dest2/dir4/file4 should be hard links */ | ||
116 | + assertIsHardlink("dest2/dir4/file3", "dest2/dir4/file4"); | ||
117 | } | ||
118 | -- | ||
119 | 2.7.4 | ||
120 | |||
diff --git a/meta/recipes-extended/libarchive/libarchive_3.2.2.bb b/meta/recipes-extended/libarchive/libarchive_3.2.2.bb index a7c1204bd2..a7ec621fb9 100644 --- a/meta/recipes-extended/libarchive/libarchive_3.2.2.bb +++ b/meta/recipes-extended/libarchive/libarchive_3.2.2.bb | |||
@@ -36,6 +36,8 @@ PACKAGECONFIG[lz4] = "--with-lz4,--without-lz4,lz4," | |||
36 | 36 | ||
37 | SRC_URI = "http://libarchive.org/downloads/libarchive-${PV}.tar.gz \ | 37 | SRC_URI = "http://libarchive.org/downloads/libarchive-${PV}.tar.gz \ |
38 | file://non-recursive-extract-and-list.patch \ | 38 | file://non-recursive-extract-and-list.patch \ |
39 | file://0001-archive_write_disk_posix.c-make-_fsobj-functions-mor.patch \ | ||
40 | file://0002-Fix-extracting-hardlinks-over-symlinks.patch \ | ||
39 | " | 41 | " |
40 | 42 | ||
41 | SRC_URI[md5sum] = "1ec00b7dcaf969dd2a5712f85f23c764" | 43 | SRC_URI[md5sum] = "1ec00b7dcaf969dd2a5712f85f23c764" |