1 /*-
2 * Copyright (c) 2003-2009 Tim Kientzle
3 * Copyright (c) 2010-2012 Michihiro NAKAJIMA
4 * Copyright (c) 2016 Martin Matuska
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "archive_platform.h"
29
30 /* This is the tree-walking code for POSIX systems. */
31 #if !defined(_WIN32) || defined(__CYGWIN__)
32
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
36 #ifdef HAVE_SYS_EXTATTR_H
37 #include <sys/extattr.h>
38 #endif
39 #ifdef HAVE_SYS_IOCTL_H
40 #include <sys/ioctl.h>
41 #endif
42 #ifdef HAVE_SYS_PARAM_H
43 #include <sys/param.h>
44 #endif
45 #ifdef HAVE_SYS_STAT_H
46 #include <sys/stat.h>
47 #endif
48 #if defined(HAVE_SYS_XATTR_H)
49 #include <sys/xattr.h>
50 #elif defined(HAVE_ATTR_XATTR_H)
51 #include <attr/xattr.h>
52 #endif
53 #ifdef HAVE_SYS_EA_H
54 #include <sys/ea.h>
55 #endif
56 #ifdef HAVE_COPYFILE_H
57 #include <copyfile.h>
58 #endif
59 #ifdef HAVE_ERRNO_H
60 #include <errno.h>
61 #endif
62 #ifdef HAVE_FCNTL_H
63 #include <fcntl.h>
64 #endif
65 #ifdef HAVE_LIMITS_H
66 #include <limits.h>
67 #endif
68 #ifdef HAVE_LINUX_TYPES_H
69 #include <linux/types.h>
70 #endif
71 #ifdef HAVE_LINUX_FIEMAP_H
72 #include <linux/fiemap.h>
73 #endif
74 #ifdef HAVE_LINUX_FS_H
75 #include <linux/fs.h>
76 #endif
77 /*
78 * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
79 * As the include guards don't agree, the order of include is important.
80 */
81 #ifdef HAVE_LINUX_EXT2_FS_H
82 #include <linux/ext2_fs.h> /* for Linux file flags */
83 #endif
84 #if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
85 #include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
86 #endif
87 #ifdef HAVE_PATHS_H
88 #include <paths.h>
89 #endif
90 #ifdef HAVE_UNISTD_H
91 #include <unistd.h>
92 #endif
93
94 #include "archive.h"
95 #include "archive_entry.h"
96 #include "archive_private.h"
97 #include "archive_read_disk_private.h"
98
99 #ifndef O_CLOEXEC
100 #define O_CLOEXEC 0
101 #endif
102
103 static int setup_mac_metadata(struct archive_read_disk *,
104 struct archive_entry *, int *fd);
105 #ifdef ARCHIVE_XATTR_FREEBSD
106 static int setup_xattrs_namespace(struct archive_read_disk *,
107 struct archive_entry *, int *, int);
108 #endif
109 static int setup_xattrs(struct archive_read_disk *,
110 struct archive_entry *, int *fd);
111 static int setup_sparse(struct archive_read_disk *,
112 struct archive_entry *, int *fd);
113 #if defined(HAVE_LINUX_FIEMAP_H)
114 static int setup_sparse_fiemap(struct archive_read_disk *,
115 struct archive_entry *, int *fd);
116 #endif
117
118 #if !ARCHIVE_ACL_SUPPORT
119 int
archive_read_disk_entry_setup_acls(struct archive_read_disk * a,struct archive_entry * entry,int * fd)120 archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
121 struct archive_entry *entry, int *fd)
122 {
123 (void)a; /* UNUSED */
124 (void)entry; /* UNUSED */
125 (void)fd; /* UNUSED */
126 return (ARCHIVE_OK);
127 }
128 #endif
129
130 /*
131 * Enter working directory and return working pathname of archive_entry.
132 * If a pointer to an integer is provided and its value is below zero
133 * open a file descriptor on this pathname.
134 */
135 const char *
archive_read_disk_entry_setup_path(struct archive_read_disk * a,struct archive_entry * entry,int * fd)136 archive_read_disk_entry_setup_path(struct archive_read_disk *a,
137 struct archive_entry *entry, int *fd)
138 {
139 const char *path;
140
141 path = archive_entry_sourcepath(entry);
142
143 if (path == NULL || (a->tree != NULL &&
144 a->tree_enter_working_dir(a->tree) != 0))
145 path = archive_entry_pathname(entry);
146 if (path == NULL) {
147 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
148 "Couldn't determine path");
149 } else if (fd != NULL && *fd < 0 && a->tree != NULL &&
150 (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)) {
151 *fd = a->open_on_current_dir(a->tree, path,
152 O_RDONLY | O_NONBLOCK);
153 }
154 return (path);
155 }
156
157 int
archive_read_disk_entry_from_file(struct archive * _a,struct archive_entry * entry,int fd,const struct stat * st)158 archive_read_disk_entry_from_file(struct archive *_a,
159 struct archive_entry *entry,
160 int fd,
161 const struct stat *st)
162 {
163 struct archive_read_disk *a = (struct archive_read_disk *)_a;
164 const char *path, *name;
165 struct stat s;
166 int initial_fd = fd;
167 int r, r1;
168
169 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
170 "archive_read_disk_entry_from_file");
171
172 archive_clear_error(_a);
173 path = archive_entry_sourcepath(entry);
174 if (path == NULL)
175 path = archive_entry_pathname(entry);
176
177 if (a->tree == NULL) {
178 if (st == NULL) {
179 #if HAVE_FSTAT
180 if (fd >= 0) {
181 if (fstat(fd, &s) != 0) {
182 archive_set_error(&a->archive, errno,
183 "Can't fstat");
184 return (ARCHIVE_FAILED);
185 }
186 } else
187 #endif
188 #if HAVE_LSTAT
189 if (!a->follow_symlinks) {
190 if (lstat(path, &s) != 0) {
191 archive_set_error(&a->archive, errno,
192 "Can't lstat %s", path);
193 return (ARCHIVE_FAILED);
194 }
195 } else
196 #endif
197 if (la_stat(path, &s) != 0) {
198 archive_set_error(&a->archive, errno,
199 "Can't stat %s", path);
200 return (ARCHIVE_FAILED);
201 }
202 st = &s;
203 }
204 archive_entry_copy_stat(entry, st);
205 }
206
207 /* Lookup uname/gname */
208 name = archive_read_disk_uname(_a, archive_entry_uid(entry));
209 if (name != NULL)
210 archive_entry_copy_uname(entry, name);
211 name = archive_read_disk_gname(_a, archive_entry_gid(entry));
212 if (name != NULL)
213 archive_entry_copy_gname(entry, name);
214
215 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
216 /* On FreeBSD, we get flags for free with the stat. */
217 /* TODO: Does this belong in copy_stat()? */
218 if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 && st->st_flags != 0)
219 archive_entry_set_fflags(entry, st->st_flags, 0);
220 #endif
221
222 #if (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
223 (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
224 /* Linux requires an extra ioctl to pull the flags. Although
225 * this is an extra step, it has a nice side-effect: We get an
226 * open file descriptor which we can use in the subsequent lookups. */
227 if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 &&
228 (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
229 if (fd < 0) {
230 if (a->tree != NULL)
231 fd = a->open_on_current_dir(a->tree, path,
232 O_RDONLY | O_NONBLOCK | O_CLOEXEC);
233 else
234 fd = open(path, O_RDONLY | O_NONBLOCK |
235 O_CLOEXEC);
236 __archive_ensure_cloexec_flag(fd);
237 }
238 if (fd >= 0) {
239 int stflags;
240 r = ioctl(fd,
241 #if defined(FS_IOC_GETFLAGS)
242 FS_IOC_GETFLAGS,
243 #else
244 EXT2_IOC_GETFLAGS,
245 #endif
246 &stflags);
247 if (r == 0 && stflags != 0)
248 archive_entry_set_fflags(entry, stflags, 0);
249 }
250 }
251 #endif
252
253 #if defined(HAVE_READLINK) || defined(HAVE_READLINKAT)
254 if (S_ISLNK(st->st_mode)) {
255 size_t linkbuffer_len = st->st_size;
256 char *linkbuffer;
257 int lnklen;
258
259 linkbuffer = malloc(linkbuffer_len + 1);
260 if (linkbuffer == NULL) {
261 archive_set_error(&a->archive, ENOMEM,
262 "Couldn't read link data");
263 return (ARCHIVE_FAILED);
264 }
265 if (a->tree != NULL) {
266 #ifdef HAVE_READLINKAT
267 lnklen = readlinkat(a->tree_current_dir_fd(a->tree),
268 path, linkbuffer, linkbuffer_len);
269 #else
270 if (a->tree_enter_working_dir(a->tree) != 0) {
271 archive_set_error(&a->archive, errno,
272 "Couldn't read link data");
273 free(linkbuffer);
274 return (ARCHIVE_FAILED);
275 }
276 lnklen = readlink(path, linkbuffer, linkbuffer_len);
277 #endif /* HAVE_READLINKAT */
278 } else
279 lnklen = readlink(path, linkbuffer, linkbuffer_len);
280 if (lnklen < 0) {
281 archive_set_error(&a->archive, errno,
282 "Couldn't read link data");
283 free(linkbuffer);
284 return (ARCHIVE_FAILED);
285 }
286 linkbuffer[lnklen] = '\0';
287 archive_entry_set_symlink(entry, linkbuffer);
288 free(linkbuffer);
289 }
290 #endif /* HAVE_READLINK || HAVE_READLINKAT */
291
292 r = 0;
293 if ((a->flags & ARCHIVE_READDISK_NO_ACL) == 0)
294 r = archive_read_disk_entry_setup_acls(a, entry, &fd);
295 if ((a->flags & ARCHIVE_READDISK_NO_XATTR) == 0) {
296 r1 = setup_xattrs(a, entry, &fd);
297 if (r1 < r)
298 r = r1;
299 }
300 if (a->flags & ARCHIVE_READDISK_MAC_COPYFILE) {
301 r1 = setup_mac_metadata(a, entry, &fd);
302 if (r1 < r)
303 r = r1;
304 }
305 if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) {
306 r1 = setup_sparse(a, entry, &fd);
307 if (r1 < r)
308 r = r1;
309 }
310
311 /* If we opened the file earlier in this function, close it. */
312 if (initial_fd != fd)
313 close(fd);
314 return (r);
315 }
316
317 #if defined(__APPLE__) && defined(HAVE_COPYFILE_H)
318 /*
319 * The Mac OS "copyfile()" API copies the extended metadata for a
320 * file into a separate file in AppleDouble format (see RFC 1740).
321 *
322 * Mac OS tar and cpio implementations store this extended
323 * metadata as a separate entry just before the regular entry
324 * with a "._" prefix added to the filename.
325 *
326 * Note that this is currently done unconditionally; the tar program has
327 * an option to discard this information before the archive is written.
328 *
329 * TODO: If there's a failure, report it and return ARCHIVE_WARN.
330 */
331 static int
setup_mac_metadata(struct archive_read_disk * a,struct archive_entry * entry,int * fd)332 setup_mac_metadata(struct archive_read_disk *a,
333 struct archive_entry *entry, int *fd)
334 {
335 int tempfd = -1;
336 int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR;
337 struct stat copyfile_stat;
338 int ret = ARCHIVE_OK;
339 void *buff = NULL;
340 int have_attrs;
341 const char *name;
342 struct archive_string tempfile;
343
344 (void)fd; /* UNUSED */
345
346 name = archive_read_disk_entry_setup_path(a, entry, NULL);
347 if (name == NULL)
348 return (ARCHIVE_WARN);
349
350 /* Short-circuit if there's nothing to do. */
351 have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
352 if (have_attrs == -1) {
353 archive_set_error(&a->archive, errno,
354 "Could not check extended attributes");
355 return (ARCHIVE_WARN);
356 }
357 if (have_attrs == 0)
358 return (ARCHIVE_OK);
359
360 archive_string_init(&tempfile);
361 archive_strcpy(&tempfile, name);
362 archive_string_dirname(&tempfile);
363 archive_strcat(&tempfile, "/tar.XXXXXXXX");
364 tempfd = __archive_mkstemp(tempfile.s);
365 if (tempfd < 0) {
366 archive_set_error(&a->archive, errno,
367 "Could not open extended attribute file");
368 ret = ARCHIVE_WARN;
369 goto cleanup;
370 }
371 __archive_ensure_cloexec_flag(tempfd);
372
373 /* XXX I wish copyfile() could pack directly to a memory
374 * buffer; that would avoid the temp file here. For that
375 * matter, it would be nice if fcopyfile() actually worked,
376 * that would reduce the many open/close races here. */
377 if (copyfile(name, tempfile.s, 0, copyfile_flags | COPYFILE_PACK)) {
378 archive_set_error(&a->archive, errno,
379 "Could not pack extended attributes");
380 ret = ARCHIVE_WARN;
381 goto cleanup;
382 }
383 if (fstat(tempfd, ©file_stat)) {
384 archive_set_error(&a->archive, errno,
385 "Could not check size of extended attributes");
386 ret = ARCHIVE_WARN;
387 goto cleanup;
388 }
389 buff = malloc(copyfile_stat.st_size);
390 if (buff == NULL) {
391 archive_set_error(&a->archive, errno,
392 "Could not allocate memory for extended attributes");
393 ret = ARCHIVE_WARN;
394 goto cleanup;
395 }
396 if (copyfile_stat.st_size != read(tempfd, buff, copyfile_stat.st_size)) {
397 archive_set_error(&a->archive, errno,
398 "Could not read extended attributes into memory");
399 ret = ARCHIVE_WARN;
400 goto cleanup;
401 }
402 archive_entry_copy_mac_metadata(entry, buff, copyfile_stat.st_size);
403
404 cleanup:
405 if (tempfd >= 0) {
406 close(tempfd);
407 unlink(tempfile.s);
408 }
409 archive_string_free(&tempfile);
410 free(buff);
411 return (ret);
412 }
413
414 #else
415
416 /*
417 * Stub implementation for non-Mac systems.
418 */
419 static int
setup_mac_metadata(struct archive_read_disk * a,struct archive_entry * entry,int * fd)420 setup_mac_metadata(struct archive_read_disk *a,
421 struct archive_entry *entry, int *fd)
422 {
423 (void)a; /* UNUSED */
424 (void)entry; /* UNUSED */
425 (void)fd; /* UNUSED */
426 return (ARCHIVE_OK);
427 }
428 #endif
429
430 #if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_AIX
431
432 /*
433 * Linux, Darwin and AIX extended attribute support.
434 *
435 * TODO: By using a stack-allocated buffer for the first
436 * call to getxattr(), we might be able to avoid the second
437 * call entirely. We only need the second call if the
438 * stack-allocated buffer is too small. But a modest buffer
439 * of 1024 bytes or so will often be big enough. Same applies
440 * to listxattr().
441 */
442
443
444 static int
setup_xattr(struct archive_read_disk * a,struct archive_entry * entry,const char * name,int fd,const char * accpath)445 setup_xattr(struct archive_read_disk *a,
446 struct archive_entry *entry, const char *name, int fd, const char *accpath)
447 {
448 ssize_t size;
449 void *value = NULL;
450
451
452 if (fd >= 0) {
453 #if ARCHIVE_XATTR_LINUX
454 size = fgetxattr(fd, name, NULL, 0);
455 #elif ARCHIVE_XATTR_DARWIN
456 size = fgetxattr(fd, name, NULL, 0, 0, 0);
457 #elif ARCHIVE_XATTR_AIX
458 size = fgetea(fd, name, NULL, 0);
459 #endif
460 } else if (!a->follow_symlinks) {
461 #if ARCHIVE_XATTR_LINUX
462 size = lgetxattr(accpath, name, NULL, 0);
463 #elif ARCHIVE_XATTR_DARWIN
464 size = getxattr(accpath, name, NULL, 0, 0, XATTR_NOFOLLOW);
465 #elif ARCHIVE_XATTR_AIX
466 size = lgetea(accpath, name, NULL, 0);
467 #endif
468 } else {
469 #if ARCHIVE_XATTR_LINUX
470 size = getxattr(accpath, name, NULL, 0);
471 #elif ARCHIVE_XATTR_DARWIN
472 size = getxattr(accpath, name, NULL, 0, 0, 0);
473 #elif ARCHIVE_XATTR_AIX
474 size = getea(accpath, name, NULL, 0);
475 #endif
476 }
477
478 if (size == -1) {
479 archive_set_error(&a->archive, errno,
480 "Couldn't query extended attribute");
481 return (ARCHIVE_WARN);
482 }
483
484 if (size > 0 && (value = malloc(size)) == NULL) {
485 archive_set_error(&a->archive, errno, "Out of memory");
486 return (ARCHIVE_FATAL);
487 }
488
489
490 if (fd >= 0) {
491 #if ARCHIVE_XATTR_LINUX
492 size = fgetxattr(fd, name, value, size);
493 #elif ARCHIVE_XATTR_DARWIN
494 size = fgetxattr(fd, name, value, size, 0, 0);
495 #elif ARCHIVE_XATTR_AIX
496 size = fgetea(fd, name, value, size);
497 #endif
498 } else if (!a->follow_symlinks) {
499 #if ARCHIVE_XATTR_LINUX
500 size = lgetxattr(accpath, name, value, size);
501 #elif ARCHIVE_XATTR_DARWIN
502 size = getxattr(accpath, name, value, size, 0, XATTR_NOFOLLOW);
503 #elif ARCHIVE_XATTR_AIX
504 size = lgetea(accpath, name, value, size);
505 #endif
506 } else {
507 #if ARCHIVE_XATTR_LINUX
508 size = getxattr(accpath, name, value, size);
509 #elif ARCHIVE_XATTR_DARWIN
510 size = getxattr(accpath, name, value, size, 0, 0);
511 #elif ARCHIVE_XATTR_AIX
512 size = getea(accpath, name, value, size);
513 #endif
514 }
515
516 if (size == -1) {
517 archive_set_error(&a->archive, errno,
518 "Couldn't read extended attribute");
519 free(value);
520 return (ARCHIVE_WARN);
521 }
522
523 archive_entry_xattr_add_entry(entry, name, value, size);
524
525 free(value);
526 return (ARCHIVE_OK);
527 }
528
529 static int
setup_xattrs(struct archive_read_disk * a,struct archive_entry * entry,int * fd)530 setup_xattrs(struct archive_read_disk *a,
531 struct archive_entry *entry, int *fd)
532 {
533 char *list, *p;
534 const char *path;
535 ssize_t list_size;
536
537 path = NULL;
538
539 if (*fd < 0) {
540 path = archive_read_disk_entry_setup_path(a, entry, fd);
541 if (path == NULL)
542 return (ARCHIVE_WARN);
543 }
544
545 if (*fd >= 0) {
546 #if ARCHIVE_XATTR_LINUX
547 list_size = flistxattr(*fd, NULL, 0);
548 #elif ARCHIVE_XATTR_DARWIN
549 list_size = flistxattr(*fd, NULL, 0, 0);
550 #elif ARCHIVE_XATTR_AIX
551 list_size = flistea(*fd, NULL, 0);
552 #endif
553 } else if (!a->follow_symlinks) {
554 #if ARCHIVE_XATTR_LINUX
555 list_size = llistxattr(path, NULL, 0);
556 #elif ARCHIVE_XATTR_DARWIN
557 list_size = listxattr(path, NULL, 0, XATTR_NOFOLLOW);
558 #elif ARCHIVE_XATTR_AIX
559 list_size = llistea(path, NULL, 0);
560 #endif
561 } else {
562 #if ARCHIVE_XATTR_LINUX
563 list_size = listxattr(path, NULL, 0);
564 #elif ARCHIVE_XATTR_DARWIN
565 list_size = listxattr(path, NULL, 0, 0);
566 #elif ARCHIVE_XATTR_AIX
567 list_size = listea(path, NULL, 0);
568 #endif
569 }
570
571 if (list_size == -1) {
572 if (errno == ENOTSUP || errno == ENOSYS)
573 return (ARCHIVE_OK);
574 archive_set_error(&a->archive, errno,
575 "Couldn't list extended attributes");
576 return (ARCHIVE_WARN);
577 }
578
579 if (list_size == 0)
580 return (ARCHIVE_OK);
581
582 if ((list = malloc(list_size)) == NULL) {
583 archive_set_error(&a->archive, errno, "Out of memory");
584 return (ARCHIVE_FATAL);
585 }
586
587 if (*fd >= 0) {
588 #if ARCHIVE_XATTR_LINUX
589 list_size = flistxattr(*fd, list, list_size);
590 #elif ARCHIVE_XATTR_DARWIN
591 list_size = flistxattr(*fd, list, list_size, 0);
592 #elif ARCHIVE_XATTR_AIX
593 list_size = flistea(*fd, list, list_size);
594 #endif
595 } else if (!a->follow_symlinks) {
596 #if ARCHIVE_XATTR_LINUX
597 list_size = llistxattr(path, list, list_size);
598 #elif ARCHIVE_XATTR_DARWIN
599 list_size = listxattr(path, list, list_size, XATTR_NOFOLLOW);
600 #elif ARCHIVE_XATTR_AIX
601 list_size = llistea(path, list, list_size);
602 #endif
603 } else {
604 #if ARCHIVE_XATTR_LINUX
605 list_size = listxattr(path, list, list_size);
606 #elif ARCHIVE_XATTR_DARWIN
607 list_size = listxattr(path, list, list_size, 0);
608 #elif ARCHIVE_XATTR_AIX
609 list_size = listea(path, list, list_size);
610 #endif
611 }
612
613 if (list_size == -1) {
614 archive_set_error(&a->archive, errno,
615 "Couldn't retrieve extended attributes");
616 free(list);
617 return (ARCHIVE_WARN);
618 }
619
620 for (p = list; (p - list) < list_size; p += strlen(p) + 1) {
621 #if ARCHIVE_XATTR_LINUX
622 /* Linux: skip POSIX.1e ACL extended attributes */
623 if (strncmp(p, "system.", 7) == 0 &&
624 (strcmp(p + 7, "posix_acl_access") == 0 ||
625 strcmp(p + 7, "posix_acl_default") == 0))
626 continue;
627 if (strncmp(p, "trusted.SGI_", 12) == 0 &&
628 (strcmp(p + 12, "ACL_DEFAULT") == 0 ||
629 strcmp(p + 12, "ACL_FILE") == 0))
630 continue;
631
632 /* Linux: xfsroot namespace is obsolete and unsupported */
633 if (strncmp(p, "xfsroot.", 8) == 0)
634 continue;
635 #endif
636 setup_xattr(a, entry, p, *fd, path);
637 }
638
639 free(list);
640 return (ARCHIVE_OK);
641 }
642
643 #elif ARCHIVE_XATTR_FREEBSD
644
645 /*
646 * FreeBSD extattr interface.
647 */
648
649 /* TODO: Implement this. Follow the Linux model above, but
650 * with FreeBSD-specific system calls, of course. Be careful
651 * to not include the system extattrs that hold ACLs; we handle
652 * those separately.
653 */
654 static int
655 setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
656 int namespace, const char *name, const char *fullname, int fd,
657 const char *path);
658
659 static int
setup_xattr(struct archive_read_disk * a,struct archive_entry * entry,int namespace,const char * name,const char * fullname,int fd,const char * accpath)660 setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
661 int namespace, const char *name, const char *fullname, int fd,
662 const char *accpath)
663 {
664 ssize_t size;
665 void *value = NULL;
666
667 if (fd >= 0)
668 size = extattr_get_fd(fd, namespace, name, NULL, 0);
669 else if (!a->follow_symlinks)
670 size = extattr_get_link(accpath, namespace, name, NULL, 0);
671 else
672 size = extattr_get_file(accpath, namespace, name, NULL, 0);
673
674 if (size == -1) {
675 archive_set_error(&a->archive, errno,
676 "Couldn't query extended attribute");
677 return (ARCHIVE_WARN);
678 }
679
680 if (size > 0 && (value = malloc(size)) == NULL) {
681 archive_set_error(&a->archive, errno, "Out of memory");
682 return (ARCHIVE_FATAL);
683 }
684
685 if (fd >= 0)
686 size = extattr_get_fd(fd, namespace, name, value, size);
687 else if (!a->follow_symlinks)
688 size = extattr_get_link(accpath, namespace, name, value, size);
689 else
690 size = extattr_get_file(accpath, namespace, name, value, size);
691
692 if (size == -1) {
693 free(value);
694 archive_set_error(&a->archive, errno,
695 "Couldn't read extended attribute");
696 return (ARCHIVE_WARN);
697 }
698
699 archive_entry_xattr_add_entry(entry, fullname, value, size);
700
701 free(value);
702 return (ARCHIVE_OK);
703 }
704
705 static int
setup_xattrs_namespace(struct archive_read_disk * a,struct archive_entry * entry,int * fd,int namespace)706 setup_xattrs_namespace(struct archive_read_disk *a,
707 struct archive_entry *entry, int *fd, int namespace)
708 {
709 char buff[512];
710 char *list, *p;
711 ssize_t list_size;
712 const char *path;
713
714 path = NULL;
715
716 if (*fd < 0) {
717 path = archive_read_disk_entry_setup_path(a, entry, fd);
718 if (path == NULL)
719 return (ARCHIVE_WARN);
720 }
721
722 if (*fd >= 0)
723 list_size = extattr_list_fd(*fd, namespace, NULL, 0);
724 else if (!a->follow_symlinks)
725 list_size = extattr_list_link(path, namespace, NULL, 0);
726 else
727 list_size = extattr_list_file(path, namespace, NULL, 0);
728
729 if (list_size == -1 && errno == EOPNOTSUPP)
730 return (ARCHIVE_OK);
731 if (list_size == -1 && errno == EPERM)
732 return (ARCHIVE_OK);
733 if (list_size == -1) {
734 archive_set_error(&a->archive, errno,
735 "Couldn't list extended attributes");
736 return (ARCHIVE_WARN);
737 }
738
739 if (list_size == 0)
740 return (ARCHIVE_OK);
741
742 if ((list = malloc(list_size)) == NULL) {
743 archive_set_error(&a->archive, errno, "Out of memory");
744 return (ARCHIVE_FATAL);
745 }
746
747 if (*fd >= 0)
748 list_size = extattr_list_fd(*fd, namespace, list, list_size);
749 else if (!a->follow_symlinks)
750 list_size = extattr_list_link(path, namespace, list, list_size);
751 else
752 list_size = extattr_list_file(path, namespace, list, list_size);
753
754 if (list_size == -1) {
755 archive_set_error(&a->archive, errno,
756 "Couldn't retrieve extended attributes");
757 free(list);
758 return (ARCHIVE_WARN);
759 }
760
761 p = list;
762 while ((p - list) < list_size) {
763 size_t len = 255 & (int)*p;
764 char *name;
765
766 if (namespace == EXTATTR_NAMESPACE_SYSTEM) {
767 if (!strcmp(p + 1, "nfs4.acl") ||
768 !strcmp(p + 1, "posix1e.acl_access") ||
769 !strcmp(p + 1, "posix1e.acl_default")) {
770 p += 1 + len;
771 continue;
772 }
773 strcpy(buff, "system.");
774 } else {
775 strcpy(buff, "user.");
776 }
777 name = buff + strlen(buff);
778 memcpy(name, p + 1, len);
779 name[len] = '\0';
780 setup_xattr(a, entry, namespace, name, buff, *fd, path);
781 p += 1 + len;
782 }
783
784 free(list);
785 return (ARCHIVE_OK);
786 }
787
788 static int
setup_xattrs(struct archive_read_disk * a,struct archive_entry * entry,int * fd)789 setup_xattrs(struct archive_read_disk *a,
790 struct archive_entry *entry, int *fd)
791 {
792 int namespaces[2];
793 int i, res;
794
795 namespaces[0] = EXTATTR_NAMESPACE_USER;
796 namespaces[1] = EXTATTR_NAMESPACE_SYSTEM;
797
798 for (i = 0; i < 2; i++) {
799 res = setup_xattrs_namespace(a, entry, fd,
800 namespaces[i]);
801 switch (res) {
802 case (ARCHIVE_OK):
803 case (ARCHIVE_WARN):
804 break;
805 default:
806 return (res);
807 }
808 }
809
810 return (ARCHIVE_OK);
811 }
812
813 #else
814
815 /*
816 * Generic (stub) extended attribute support.
817 */
818 static int
setup_xattrs(struct archive_read_disk * a,struct archive_entry * entry,int * fd)819 setup_xattrs(struct archive_read_disk *a,
820 struct archive_entry *entry, int *fd)
821 {
822 (void)a; /* UNUSED */
823 (void)entry; /* UNUSED */
824 (void)fd; /* UNUSED */
825 return (ARCHIVE_OK);
826 }
827
828 #endif
829
830 #if defined(HAVE_LINUX_FIEMAP_H)
831
832 /*
833 * Linux FIEMAP sparse interface.
834 *
835 * The FIEMAP ioctl returns an "extent" for each physical allocation
836 * on disk. We need to process those to generate a more compact list
837 * of logical file blocks. We also need to be very careful to use
838 * FIEMAP_FLAG_SYNC here, since there are reports that Linux sometimes
839 * does not report allocations for newly-written data that hasn't
840 * been synced to disk.
841 *
842 * It's important to return a minimal sparse file list because we want
843 * to not trigger sparse file extensions if we don't have to, since
844 * not all readers support them.
845 */
846
847 static int
setup_sparse_fiemap(struct archive_read_disk * a,struct archive_entry * entry,int * fd)848 setup_sparse_fiemap(struct archive_read_disk *a,
849 struct archive_entry *entry, int *fd)
850 {
851 char buff[4096];
852 struct fiemap *fm;
853 struct fiemap_extent *fe;
854 int64_t size;
855 int count, do_fiemap, iters;
856 int exit_sts = ARCHIVE_OK;
857 const char *path;
858
859 if (archive_entry_filetype(entry) != AE_IFREG
860 || archive_entry_size(entry) <= 0
861 || archive_entry_hardlink(entry) != NULL)
862 return (ARCHIVE_OK);
863
864 if (*fd < 0) {
865 path = archive_read_disk_entry_setup_path(a, entry, NULL);
866 if (path == NULL)
867 return (ARCHIVE_FAILED);
868
869 if (a->tree != NULL)
870 *fd = a->open_on_current_dir(a->tree, path,
871 O_RDONLY | O_NONBLOCK | O_CLOEXEC);
872 else
873 *fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
874 if (*fd < 0) {
875 archive_set_error(&a->archive, errno,
876 "Can't open `%s'", path);
877 return (ARCHIVE_FAILED);
878 }
879 __archive_ensure_cloexec_flag(*fd);
880 }
881
882 /* Initialize buffer to avoid the error valgrind complains about. */
883 memset(buff, 0, sizeof(buff));
884 count = (sizeof(buff) - sizeof(*fm))/sizeof(*fe);
885 fm = (struct fiemap *)buff;
886 fm->fm_start = 0;
887 fm->fm_length = ~0ULL;
888 fm->fm_flags = FIEMAP_FLAG_SYNC;
889 fm->fm_extent_count = count;
890 do_fiemap = 1;
891 size = archive_entry_size(entry);
892 for (iters = 0; ; ++iters) {
893 int i, r;
894
895 r = ioctl(*fd, FS_IOC_FIEMAP, fm);
896 if (r < 0) {
897 /* When something error happens, it is better we
898 * should return ARCHIVE_OK because an earlier
899 * version(<2.6.28) cannot perform FS_IOC_FIEMAP. */
900 goto exit_setup_sparse_fiemap;
901 }
902 if (fm->fm_mapped_extents == 0) {
903 if (iters == 0) {
904 /* Fully sparse file; insert a zero-length "data" entry */
905 archive_entry_sparse_add_entry(entry, 0, 0);
906 }
907 break;
908 }
909 fe = fm->fm_extents;
910 for (i = 0; i < (int)fm->fm_mapped_extents; i++, fe++) {
911 if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
912 /* The fe_length of the last block does not
913 * adjust itself to its size files. */
914 int64_t length = fe->fe_length;
915 if (fe->fe_logical + length > (uint64_t)size)
916 length -= fe->fe_logical + length - size;
917 if (fe->fe_logical == 0 && length == size) {
918 /* This is not sparse. */
919 do_fiemap = 0;
920 break;
921 }
922 if (length > 0)
923 archive_entry_sparse_add_entry(entry,
924 fe->fe_logical, length);
925 }
926 if (fe->fe_flags & FIEMAP_EXTENT_LAST)
927 do_fiemap = 0;
928 }
929 if (do_fiemap) {
930 fe = fm->fm_extents + fm->fm_mapped_extents -1;
931 fm->fm_start = fe->fe_logical + fe->fe_length;
932 } else
933 break;
934 }
935 exit_setup_sparse_fiemap:
936 return (exit_sts);
937 }
938
939 #if !defined(SEEK_HOLE) || !defined(SEEK_DATA)
940 static int
setup_sparse(struct archive_read_disk * a,struct archive_entry * entry,int * fd)941 setup_sparse(struct archive_read_disk *a,
942 struct archive_entry *entry, int *fd)
943 {
944 return setup_sparse_fiemap(a, entry, fd);
945 }
946 #endif
947 #endif /* defined(HAVE_LINUX_FIEMAP_H) */
948
949 #if defined(SEEK_HOLE) && defined(SEEK_DATA)
950
951 /*
952 * SEEK_HOLE sparse interface (FreeBSD, Linux, Solaris)
953 */
954
955 static int
setup_sparse(struct archive_read_disk * a,struct archive_entry * entry,int * fd)956 setup_sparse(struct archive_read_disk *a,
957 struct archive_entry *entry, int *fd)
958 {
959 int64_t size;
960 off_t initial_off;
961 off_t off_s, off_e;
962 int exit_sts = ARCHIVE_OK;
963 int check_fully_sparse = 0;
964 const char *path;
965
966 if (archive_entry_filetype(entry) != AE_IFREG
967 || archive_entry_size(entry) <= 0
968 || archive_entry_hardlink(entry) != NULL)
969 return (ARCHIVE_OK);
970
971 /* Does filesystem support the reporting of hole ? */
972 if (*fd < 0)
973 path = archive_read_disk_entry_setup_path(a, entry, fd);
974 else
975 path = NULL;
976
977 if (*fd >= 0) {
978 #ifdef _PC_MIN_HOLE_SIZE
979 if (fpathconf(*fd, _PC_MIN_HOLE_SIZE) <= 0)
980 return (ARCHIVE_OK);
981 #endif
982 initial_off = lseek(*fd, 0, SEEK_CUR);
983 if (initial_off != 0)
984 lseek(*fd, 0, SEEK_SET);
985 } else {
986 if (path == NULL)
987 return (ARCHIVE_FAILED);
988 #ifdef _PC_MIN_HOLE_SIZE
989 if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0)
990 return (ARCHIVE_OK);
991 #endif
992 *fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
993 if (*fd < 0) {
994 archive_set_error(&a->archive, errno,
995 "Can't open `%s'", path);
996 return (ARCHIVE_FAILED);
997 }
998 __archive_ensure_cloexec_flag(*fd);
999 initial_off = 0;
1000 }
1001
1002 #ifndef _PC_MIN_HOLE_SIZE
1003 /* Check if the underlying filesystem supports seek hole */
1004 off_s = lseek(*fd, 0, SEEK_HOLE);
1005 if (off_s < 0)
1006 #if defined(HAVE_LINUX_FIEMAP_H)
1007 return setup_sparse_fiemap(a, entry, fd);
1008 #else
1009 goto exit_setup_sparse;
1010 #endif
1011 else if (off_s > 0)
1012 lseek(*fd, 0, SEEK_SET);
1013 #endif
1014
1015 off_s = 0;
1016 size = archive_entry_size(entry);
1017 while (off_s < size) {
1018 off_s = lseek(*fd, off_s, SEEK_DATA);
1019 if (off_s == (off_t)-1) {
1020 if (errno == ENXIO) {
1021 /* no more hole */
1022 if (archive_entry_sparse_count(entry) == 0) {
1023 /* Potentially a fully-sparse file. */
1024 check_fully_sparse = 1;
1025 }
1026 break;
1027 }
1028 archive_set_error(&a->archive, errno,
1029 "lseek(SEEK_HOLE) failed");
1030 exit_sts = ARCHIVE_FAILED;
1031 goto exit_setup_sparse;
1032 }
1033 off_e = lseek(*fd, off_s, SEEK_HOLE);
1034 if (off_e == (off_t)-1) {
1035 if (errno == ENXIO) {
1036 off_e = lseek(*fd, 0, SEEK_END);
1037 if (off_e != (off_t)-1)
1038 break;/* no more data */
1039 }
1040 archive_set_error(&a->archive, errno,
1041 "lseek(SEEK_DATA) failed");
1042 exit_sts = ARCHIVE_FAILED;
1043 goto exit_setup_sparse;
1044 }
1045 if (off_s == 0 && off_e == size)
1046 break;/* This is not sparse. */
1047 archive_entry_sparse_add_entry(entry, off_s,
1048 off_e - off_s);
1049 off_s = off_e;
1050 }
1051
1052 if (check_fully_sparse) {
1053 if (lseek(*fd, 0, SEEK_HOLE) == 0 &&
1054 lseek(*fd, 0, SEEK_END) == size) {
1055 /* Fully sparse file; insert a zero-length "data" entry */
1056 archive_entry_sparse_add_entry(entry, 0, 0);
1057 }
1058 }
1059 exit_setup_sparse:
1060 lseek(*fd, initial_off, SEEK_SET);
1061 return (exit_sts);
1062 }
1063
1064 #elif !defined(HAVE_LINUX_FIEMAP_H)
1065
1066 /*
1067 * Generic (stub) sparse support.
1068 */
1069 static int
setup_sparse(struct archive_read_disk * a,struct archive_entry * entry,int * fd)1070 setup_sparse(struct archive_read_disk *a,
1071 struct archive_entry *entry, int *fd)
1072 {
1073 (void)a; /* UNUSED */
1074 (void)entry; /* UNUSED */
1075 (void)fd; /* UNUSED */
1076 return (ARCHIVE_OK);
1077 }
1078
1079 #endif
1080
1081 #endif /* !defined(_WIN32) || defined(__CYGWIN__) */
1082
1083