• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/stat.h>
6 #if defined(HAVE_ZLIB)
7 #include <zlib.h>
8 #endif
9 #include "erofs/print.h"
10 #include "erofs/cache.h"
11 #include "erofs/diskbuf.h"
12 #include "erofs/inode.h"
13 #include "erofs/list.h"
14 #include "erofs/tar.h"
15 #include "erofs/io.h"
16 #include "erofs/xattr.h"
17 #include "erofs/blobchunk.h"
18 #include "erofs/rebuild.h"
19 
20 /* This file is a tape/volume header.  Ignore it on extraction.  */
21 #define GNUTYPE_VOLHDR 'V'
22 
23 struct tar_header {
24 	char name[100];		/*   0-99 */
25 	char mode[8];		/* 100-107 */
26 	char uid[8];		/* 108-115 */
27 	char gid[8];		/* 116-123 */
28 	char size[12];		/* 124-135 */
29 	char mtime[12];		/* 136-147 */
30 	char chksum[8];		/* 148-155 */
31 	char typeflag;		/* 156-156 */
32 	char linkname[100];	/* 157-256 */
33 	char magic[6];		/* 257-262 */
34 	char version[2];	/* 263-264 */
35 	char uname[32];		/* 265-296 */
36 	char gname[32];		/* 297-328 */
37 	char devmajor[8];	/* 329-336 */
38 	char devminor[8];	/* 337-344 */
39 	char prefix[155];	/* 345-499 */
40 	char padding[12];	/* 500-512 (pad to exactly the 512 byte) */
41 };
42 
erofs_read_from_fd(int fd,void * buf,u64 bytes)43 s64 erofs_read_from_fd(int fd, void *buf, u64 bytes)
44 {
45 	s64 i = 0;
46 
47 	while (bytes) {
48 		int len = bytes > INT_MAX ? INT_MAX : bytes;
49 		int ret;
50 
51 		ret = read(fd, buf + i, len);
52 		if (ret < 1) {
53 			if (ret == 0) {
54 				break;
55 			} else if (errno != EINTR) {
56 				erofs_err("failed to read : %s\n",
57 					  strerror(errno));
58 				return -errno;
59 			}
60 		}
61 		bytes -= ret;
62 		i += ret;
63         }
64         return i;
65 }
66 
erofs_iostream_close(struct erofs_iostream * ios)67 void erofs_iostream_close(struct erofs_iostream *ios)
68 {
69 	free(ios->buffer);
70 	if (ios->decoder == EROFS_IOS_DECODER_GZIP) {
71 #if defined(HAVE_ZLIB)
72 		gzclose(ios->handler);
73 #endif
74 		return;
75 	}
76 	close(ios->fd);
77 }
78 
erofs_iostream_open(struct erofs_iostream * ios,int fd,int decoder)79 int erofs_iostream_open(struct erofs_iostream *ios, int fd, int decoder)
80 {
81 	s64 fsz;
82 
83 	ios->tail = ios->head = 0;
84 	ios->decoder = decoder;
85 	if (decoder == EROFS_IOS_DECODER_GZIP) {
86 #if defined(HAVE_ZLIB)
87 		ios->handler = gzdopen(fd, "r");
88 		if (!ios->handler)
89 			return -ENOMEM;
90 		ios->sz = fsz = 0;
91 		ios->bufsize = 32768;
92 #else
93 		return -EOPNOTSUPP;
94 #endif
95 	} else {
96 		ios->fd = fd;
97 		fsz = lseek(fd, 0, SEEK_END);
98 		if (fsz <= 0) {
99 			ios->feof = !fsz;
100 			ios->sz = 0;
101 		} else {
102 			ios->feof = false;
103 			ios->sz = fsz;
104 			if (lseek(fd, 0, SEEK_SET))
105 				return -EIO;
106 #ifdef HAVE_POSIX_FADVISE
107 			if (posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL))
108 				erofs_warn("failed to fadvise: %s, ignored.",
109 					   erofs_strerror(errno));
110 #endif
111 		}
112 		ios->bufsize = 16384;
113 	}
114 
115 	do {
116 		ios->buffer = malloc(ios->bufsize);
117 		if (ios->buffer)
118 			break;
119 		ios->bufsize >>= 1;
120 	} while (ios->bufsize >= 1024);
121 
122 	if (!ios->buffer)
123 		return -ENOMEM;
124 	return 0;
125 }
126 
erofs_iostream_read(struct erofs_iostream * ios,void ** buf,u64 bytes)127 int erofs_iostream_read(struct erofs_iostream *ios, void **buf, u64 bytes)
128 {
129 	unsigned int rabytes = ios->tail - ios->head;
130 	int ret;
131 
132 	if (rabytes >= bytes) {
133 		*buf = ios->buffer + ios->head;
134 		ios->head += bytes;
135 		return bytes;
136 	}
137 
138 	if (ios->head) {
139 		memmove(ios->buffer, ios->buffer + ios->head, rabytes);
140 		ios->head = 0;
141 		ios->tail = rabytes;
142 	}
143 
144 	if (!ios->feof) {
145 		if (ios->decoder == EROFS_IOS_DECODER_GZIP) {
146 #if defined(HAVE_ZLIB)
147 			ret = gzread(ios->handler, ios->buffer + rabytes,
148 				     ios->bufsize - rabytes);
149 			if (!ret) {
150 				int errnum;
151 				const char *errstr;
152 
153 				errstr = gzerror(ios->handler, &errnum);
154 				if (errnum != Z_STREAM_END) {
155 					erofs_err("failed to gzread: %s", errstr);
156 					return -EIO;
157 				}
158 				ios->feof = true;
159 			}
160 			ios->tail += ret;
161 #else
162 			return -EOPNOTSUPP;
163 #endif
164 		} else {
165 			ret = erofs_read_from_fd(ios->fd, ios->buffer + rabytes,
166 						 ios->bufsize - rabytes);
167 			if (ret < 0)
168 				return ret;
169 			ios->tail += ret;
170 			if (ret < ios->bufsize - rabytes)
171 				ios->feof = true;
172 		}
173 	}
174 	*buf = ios->buffer;
175 	ret = min_t(int, ios->tail, bytes);
176 	ios->head = ret;
177 	return ret;
178 }
179 
erofs_iostream_bread(struct erofs_iostream * ios,void * buf,u64 bytes)180 int erofs_iostream_bread(struct erofs_iostream *ios, void *buf, u64 bytes)
181 {
182 	u64 rem = bytes;
183 	void *src;
184 	int ret;
185 
186 	do {
187 		ret = erofs_iostream_read(ios, &src, rem);
188 		if (ret < 0)
189 			return ret;
190 		memcpy(buf, src, ret);
191 		rem -= ret;
192 	} while (rem && ret);
193 
194 	return bytes - rem;
195 }
196 
erofs_iostream_lskip(struct erofs_iostream * ios,u64 sz)197 int erofs_iostream_lskip(struct erofs_iostream *ios, u64 sz)
198 {
199 	unsigned int rabytes = ios->tail - ios->head;
200 	int ret;
201 	void *dummy;
202 
203 	if (rabytes >= sz) {
204 		ios->head += sz;
205 		return 0;
206 	}
207 
208 	sz -= rabytes;
209 	ios->head = ios->tail = 0;
210 	if (ios->feof)
211 		return sz;
212 
213 	if (ios->sz) {
214 		s64 cur = lseek(ios->fd, sz, SEEK_CUR);
215 
216 		if (cur > ios->sz)
217 			return cur - ios->sz;
218 		return 0;
219 	}
220 
221 	do {
222 		ret = erofs_iostream_read(ios, &dummy, sz);
223 		if (ret < 0)
224 			return ret;
225 		sz -= ret;
226 	} while (!(ios->feof || !ret || !sz));
227 
228 	return sz;
229 }
230 
tarerofs_otoi(const char * ptr,int len)231 static long long tarerofs_otoi(const char *ptr, int len)
232 {
233 	char inp[32];
234 	char *endp = inp;
235 	long long val;
236 
237 	memcpy(inp, ptr, len);
238 	inp[len] = '\0';
239 
240 	errno = 0;
241 	val = strtol(ptr, &endp, 8);
242 	if ((!val && endp == inp) |
243 	     (*endp && *endp != ' '))
244 		errno = EINVAL;
245 	return val;
246 }
247 
tarerofs_parsenum(const char * ptr,int len)248 static long long tarerofs_parsenum(const char *ptr, int len)
249 {
250 	/*
251 	 * For fields containing numbers or timestamps that are out of range
252 	 * for the basic format, the GNU format uses a base-256 representation
253 	 * instead of an ASCII octal number.
254 	 */
255 	if (*(char *)ptr == '\200') {
256 		long long res = 0;
257 
258 		while (--len)
259 			res = (res << 8) + (u8)*(++ptr);
260 		return res;
261 	}
262 	return tarerofs_otoi(ptr, len);
263 }
264 
265 struct tarerofs_xattr_item {
266 	struct list_head list;
267 	char *kv;
268 	unsigned int len, namelen;
269 };
270 
tarerofs_insert_xattr(struct list_head * xattrs,char * kv,int namelen,int len,bool skip)271 int tarerofs_insert_xattr(struct list_head *xattrs,
272 			  char *kv, int namelen, int len, bool skip)
273 {
274 	struct tarerofs_xattr_item *item;
275 	char *nv;
276 
277 	DBG_BUGON(namelen >= len);
278 	list_for_each_entry(item, xattrs, list) {
279 		if (!strncmp(item->kv, kv, namelen + 1)) {
280 			if (skip)
281 				return 0;
282 			goto found;
283 		}
284 	}
285 
286 	item = malloc(sizeof(*item));
287 	if (!item)
288 		return -ENOMEM;
289 	item->kv = NULL;
290 	item->namelen = namelen;
291 	namelen = 0;
292 	list_add_tail(&item->list, xattrs);
293 found:
294 	nv = realloc(item->kv, len);
295 	if (!nv)
296 		return -ENOMEM;
297 	item->kv = nv;
298 	item->len = len;
299 	memcpy(nv + namelen, kv + namelen, len - namelen);
300 	return 0;
301 }
302 
tarerofs_merge_xattrs(struct list_head * dst,struct list_head * src)303 int tarerofs_merge_xattrs(struct list_head *dst, struct list_head *src)
304 {
305 	struct tarerofs_xattr_item *item;
306 
307 	list_for_each_entry(item, src, list) {
308 		int ret;
309 
310 		ret = tarerofs_insert_xattr(dst, item->kv, item->namelen,
311 					    item->len, true);
312 		if (ret)
313 			return ret;
314 	}
315 	return 0;
316 }
317 
tarerofs_remove_xattrs(struct list_head * xattrs)318 void tarerofs_remove_xattrs(struct list_head *xattrs)
319 {
320 	struct tarerofs_xattr_item *item, *n;
321 
322 	list_for_each_entry_safe(item, n, xattrs, list) {
323 		DBG_BUGON(!item->kv);
324 		free(item->kv);
325 		list_del(&item->list);
326 		free(item);
327 	}
328 }
329 
tarerofs_apply_xattrs(struct erofs_inode * inode,struct list_head * xattrs)330 int tarerofs_apply_xattrs(struct erofs_inode *inode, struct list_head *xattrs)
331 {
332 	struct tarerofs_xattr_item *item;
333 	int ret;
334 
335 	list_for_each_entry(item, xattrs, list) {
336 		const char *v = item->kv + item->namelen + 1;
337 		unsigned int vsz = item->len - item->namelen - 1;
338 
339 		if (item->len <= item->namelen - 1) {
340 			DBG_BUGON(item->len < item->namelen - 1);
341 			continue;
342 		}
343 		item->kv[item->namelen] = '\0';
344 		erofs_dbg("Recording xattr(%s)=\"%s\" (of %u bytes) to file %s",
345 			  item->kv, v, vsz, inode->i_srcpath);
346 		ret = erofs_setxattr(inode, item->kv, v, vsz);
347 		if (ret == -ENODATA)
348 			erofs_err("Failed to set xattr(%s)=%s to file %s",
349 				  item->kv, v, inode->i_srcpath);
350 		else if (ret)
351 			return ret;
352 	}
353 	return 0;
354 }
355 
356 static const char lookup_table[65] =
357 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
358 
base64_decode(const char * src,int len,u8 * dst)359 static int base64_decode(const char *src, int len, u8 *dst)
360 {
361 	int i, bits = 0, ac = 0;
362 	const char *p;
363 	u8 *cp = dst;
364 
365 	if(!(len % 4)) {
366 		/* Check for and ignore any end padding */
367 		if (src[len - 2] == '=' && src[len - 1] == '=')
368 			len -= 2;
369 		else if (src[len - 1] == '=')
370 			--len;
371 	}
372 
373 	for (i = 0; i < len; i++) {
374 		p = strchr(lookup_table, src[i]);
375 		if (p == NULL || src[i] == 0)
376 			return -2;
377 		ac += (p - lookup_table) << bits;
378 		bits += 6;
379 		if (bits >= 8) {
380 			*cp++ = ac & 0xff;
381 			ac >>= 8;
382 			bits -= 8;
383 		}
384 	}
385 	if (ac)
386 		return -1;
387 	return cp - dst;
388 }
389 
tarerofs_parse_pax_header(struct erofs_iostream * ios,struct erofs_pax_header * eh,u32 size)390 int tarerofs_parse_pax_header(struct erofs_iostream *ios,
391 			      struct erofs_pax_header *eh, u32 size)
392 {
393 	char *buf, *p;
394 	int ret;
395 
396 	buf = malloc(size);
397 	if (!buf)
398 		return -ENOMEM;
399 	p = buf;
400 
401 	ret = erofs_iostream_bread(ios, buf, size);
402 	if (ret != size)
403 		goto out;
404 
405 	while (p < buf + size) {
406 		char *kv, *value;
407 		int len, n;
408 		/* extended records are of the format: "LEN NAME=VALUE\n" */
409 		ret = sscanf(p, "%d %n", &len, &n);
410 		if (ret < 1 || len <= n || len > buf + size - p) {
411 			ret = -EIO;
412 			goto out;
413 		}
414 		kv = p + n;
415 		p += len;
416 		len -= n;
417 
418 		if (p[-1] != '\n') {
419 			ret = -EIO;
420 			goto out;
421 		}
422 		p[-1] = '\0';
423 
424 		value = memchr(kv, '=', p - kv);
425 		if (!value) {
426 			ret = -EIO;
427 			goto out;
428 		} else {
429 			long long lln;
430 
431 			value++;
432 
433 			if (!strncmp(kv, "path=", sizeof("path=") - 1)) {
434 				int j = p - 1 - value;
435 				free(eh->path);
436 				eh->path = strdup(value);
437 				while (eh->path[j - 1] == '/')
438 					eh->path[--j] = '\0';
439 			} else if (!strncmp(kv, "linkpath=",
440 					sizeof("linkpath=") - 1)) {
441 				free(eh->link);
442 				eh->link = strdup(value);
443 			} else if (!strncmp(kv, "mtime=",
444 					sizeof("mtime=") - 1)) {
445 				ret = sscanf(value, "%lld %n", &lln, &n);
446 				if(ret < 1) {
447 					ret = -EIO;
448 					goto out;
449 				}
450 				eh->st.st_mtime = lln;
451 				if (value[n] == '.') {
452 					ret = sscanf(value + n + 1, "%d", &n);
453 					if (ret < 1) {
454 						ret = -EIO;
455 						goto out;
456 					}
457 #if ST_MTIM_NSEC
458 					ST_MTIM_NSEC(&eh->st) = n;
459 #endif
460 				}
461 				eh->use_mtime = true;
462 			} else if (!strncmp(kv, "size=",
463 					sizeof("size=") - 1)) {
464 				ret = sscanf(value, "%lld %n", &lln, &n);
465 				if(ret < 1 || value[n] != '\0') {
466 					ret = -EIO;
467 					goto out;
468 				}
469 				eh->st.st_size = lln;
470 				eh->use_size = true;
471 			} else if (!strncmp(kv, "uid=", sizeof("uid=") - 1)) {
472 				ret = sscanf(value, "%lld %n", &lln, &n);
473 				if(ret < 1 || value[n] != '\0') {
474 					ret = -EIO;
475 					goto out;
476 				}
477 				eh->st.st_uid = lln;
478 				eh->use_uid = true;
479 			} else if (!strncmp(kv, "gid=", sizeof("gid=") - 1)) {
480 				ret = sscanf(value, "%lld %n", &lln, &n);
481 				if(ret < 1 || value[n] != '\0') {
482 					ret = -EIO;
483 					goto out;
484 				}
485 				eh->st.st_gid = lln;
486 				eh->use_gid = true;
487 			} else if (!strncmp(kv, "SCHILY.xattr.",
488 				   sizeof("SCHILY.xattr.") - 1)) {
489 				char *key = kv + sizeof("SCHILY.xattr.") - 1;
490 
491 				--len; /* p[-1] == '\0' */
492 				ret = tarerofs_insert_xattr(&eh->xattrs, key,
493 						value - key - 1,
494 						len - (key - kv), false);
495 				if (ret)
496 					goto out;
497 			} else if (!strncmp(kv, "LIBARCHIVE.xattr.",
498 				   sizeof("LIBARCHIVE.xattr.") - 1)) {
499 				char *key;
500 				key = kv + sizeof("LIBARCHIVE.xattr.") - 1;
501 
502 				--len; /* p[-1] == '\0' */
503 				ret = base64_decode(value, len - (value - kv),
504 						    (u8 *)value);
505 				if (ret < 0) {
506 					ret = -EFSCORRUPTED;
507 					goto out;
508 				}
509 
510 				ret = tarerofs_insert_xattr(&eh->xattrs, key,
511 						value - key - 1,
512 						value - key + ret, false);
513 				if (ret)
514 					goto out;
515 			} else {
516 				erofs_info("unrecognized pax keyword \"%s\", ignoring", kv);
517 			}
518 		}
519 	}
520 	ret = 0;
521 out:
522 	free(buf);
523 	return ret;
524 }
525 
tarerofs_remove_inode(struct erofs_inode * inode)526 void tarerofs_remove_inode(struct erofs_inode *inode)
527 {
528 	struct erofs_dentry *d;
529 
530 	--inode->i_nlink;
531 	if (!S_ISDIR(inode->i_mode))
532 		return;
533 
534 	/* remove all subdirss */
535 	list_for_each_entry(d, &inode->i_subdirs, d_child) {
536 		if (!is_dot_dotdot(d->name))
537 			tarerofs_remove_inode(d->inode);
538 		erofs_iput(d->inode);
539 		d->inode = NULL;
540 	}
541 	--inode->i_parent->i_nlink;
542 }
543 
tarerofs_write_file_data(struct erofs_inode * inode,struct erofs_tarfile * tar)544 static int tarerofs_write_file_data(struct erofs_inode *inode,
545 				    struct erofs_tarfile *tar)
546 {
547 	unsigned int j;
548 	void *buf;
549 	int fd, nread;
550 	u64 off;
551 
552 	if (!inode->i_diskbuf) {
553 		inode->i_diskbuf = calloc(1, sizeof(*inode->i_diskbuf));
554 		if (!inode->i_diskbuf)
555 			return -ENOSPC;
556 	} else {
557 		erofs_diskbuf_close(inode->i_diskbuf);
558 	}
559 
560 	fd = erofs_diskbuf_reserve(inode->i_diskbuf, 0, &off);
561 	if (fd < 0)
562 		return -EBADF;
563 
564 	for (j = inode->i_size; j; ) {
565 		nread = erofs_iostream_read(&tar->ios, &buf, j);
566 		if (nread < 0)
567 			break;
568 		if (write(fd, buf, nread) != nread) {
569 			nread = -EIO;
570 			break;
571 		}
572 		j -= nread;
573 	}
574 	erofs_diskbuf_commit(inode->i_diskbuf, inode->i_size);
575 	inode->with_diskbuf = true;
576 	return 0;
577 }
578 
tarerofs_write_file_index(struct erofs_inode * inode,struct erofs_tarfile * tar,erofs_off_t data_offset)579 static int tarerofs_write_file_index(struct erofs_inode *inode,
580 		struct erofs_tarfile *tar, erofs_off_t data_offset)
581 {
582 	int ret;
583 
584 	ret = tarerofs_write_chunkes(inode, data_offset);
585 	if (ret)
586 		return ret;
587 	if (erofs_iostream_lskip(&tar->ios, inode->i_size))
588 		return -EIO;
589 	return 0;
590 }
591 
tarerofs_parse_tar(struct erofs_inode * root,struct erofs_tarfile * tar)592 int tarerofs_parse_tar(struct erofs_inode *root, struct erofs_tarfile *tar)
593 {
594 	char path[PATH_MAX];
595 	struct erofs_pax_header eh = tar->global;
596 	struct erofs_sb_info *sbi = root->sbi;
597 	bool whout, opq, e = false;
598 	struct stat st;
599 	erofs_off_t tar_offset, data_offset;
600 
601 	struct tar_header *th;
602 	struct erofs_dentry *d;
603 	struct erofs_inode *inode;
604 	unsigned int j, csum, cksum;
605 	int ckksum, ret, rem;
606 
607 	if (eh.path)
608 		eh.path = strdup(eh.path);
609 	if (eh.link)
610 		eh.link = strdup(eh.link);
611 	init_list_head(&eh.xattrs);
612 
613 restart:
614 	rem = tar->offset & 511;
615 	if (rem) {
616 		if (erofs_iostream_lskip(&tar->ios, 512 - rem)) {
617 			ret = -EIO;
618 			goto out;
619 		}
620 		tar->offset += 512 - rem;
621 	}
622 
623 	tar_offset = tar->offset;
624 	ret = erofs_iostream_read(&tar->ios, (void **)&th, sizeof(*th));
625 	if (ret != sizeof(*th)) {
626 		erofs_err("failed to read header block @ %llu", tar_offset);
627 		ret = -EIO;
628 		goto out;
629 	}
630 	tar->offset += sizeof(*th);
631 	if (*th->name == '\0') {
632 		if (e) {	/* end of tar 2 empty blocks */
633 			ret = 1;
634 			goto out;
635 		}
636 		e = true;	/* empty jump to next block */
637 		goto restart;
638 	}
639 
640 	/* chksum field itself treated as ' ' */
641 	csum = tarerofs_otoi(th->chksum, sizeof(th->chksum));
642 	if (errno) {
643 		erofs_err("invalid chksum @ %llu", tar_offset);
644 		ret = -EBADMSG;
645 		goto out;
646 	}
647 	cksum = 0;
648 	for (j = 0; j < 8; ++j)
649 		cksum += (unsigned int)' ';
650 	ckksum = cksum;
651 	for (j = 0; j < 148; ++j) {
652 		cksum += (unsigned int)((u8*)th)[j];
653 		ckksum += (int)((char*)th)[j];
654 	}
655 	for (j = 156; j < 500; ++j) {
656 		cksum += (unsigned int)((u8*)th)[j];
657 		ckksum += (int)((char*)th)[j];
658 	}
659 	if (csum != cksum && csum != ckksum) {
660 		erofs_err("chksum mismatch @ %llu", tar_offset);
661 		ret = -EBADMSG;
662 		goto out;
663 	}
664 
665 	if (th->typeflag == GNUTYPE_VOLHDR) {
666 		if (th->size[0])
667 			erofs_warn("GNUTYPE_VOLHDR with non-zeroed size @ %llu",
668 				   tar_offset);
669 		/* anyway, strncpy could cause some GCC warning here */
670 		memcpy(sbi->volume_name, th->name, sizeof(sbi->volume_name));
671 		goto restart;
672 	}
673 
674 	if (memcmp(th->magic, "ustar", 5)) {
675 		erofs_err("invalid tar magic @ %llu", tar_offset);
676 		ret = -EIO;
677 		goto out;
678 	}
679 
680 	st.st_mode = tarerofs_otoi(th->mode, sizeof(th->mode));
681 	if (errno)
682 		goto invalid_tar;
683 
684 	if (eh.use_uid) {
685 		st.st_uid = eh.st.st_uid;
686 	} else {
687 		st.st_uid = tarerofs_parsenum(th->uid, sizeof(th->uid));
688 		if (errno)
689 			goto invalid_tar;
690 	}
691 
692 	if (eh.use_gid) {
693 		st.st_gid = eh.st.st_gid;
694 	} else {
695 		st.st_gid = tarerofs_parsenum(th->gid, sizeof(th->gid));
696 		if (errno)
697 			goto invalid_tar;
698 	}
699 
700 	if (eh.use_size) {
701 		st.st_size = eh.st.st_size;
702 	} else {
703 		st.st_size = tarerofs_parsenum(th->size, sizeof(th->size));
704 		if (errno)
705 			goto invalid_tar;
706 	}
707 
708 	if (eh.use_mtime) {
709 		st.st_mtime = eh.st.st_mtime;
710 #if ST_MTIM_NSEC
711 		ST_MTIM_NSEC(&st) = ST_MTIM_NSEC(&eh.st);
712 #endif
713 	} else {
714 		st.st_mtime = tarerofs_parsenum(th->mtime, sizeof(th->mtime));
715 		if (errno)
716 			goto invalid_tar;
717 	}
718 
719 	if (th->typeflag <= '7' && !eh.path) {
720 		eh.path = path;
721 		j = 0;
722 		if (*th->prefix) {
723 			memcpy(path, th->prefix, sizeof(th->prefix));
724 			path[sizeof(th->prefix)] = '\0';
725 			j = strlen(path);
726 			if (path[j - 1] != '/') {
727 				path[j] = '/';
728 				path[++j] = '\0';
729 			}
730 		}
731 		memcpy(path + j, th->name, sizeof(th->name));
732 		path[j + sizeof(th->name)] = '\0';
733 		j = strlen(path);
734 		while (path[j - 1] == '/')
735 			path[--j] = '\0';
736 	}
737 
738 	data_offset = tar->offset;
739 	tar->offset += st.st_size;
740 	switch(th->typeflag) {
741 	case '0':
742 	case '7':
743 	case '1':
744 		st.st_mode |= S_IFREG;
745 		break;
746 	case '2':
747 		st.st_mode |= S_IFLNK;
748 		break;
749 	case '3':
750 		st.st_mode |= S_IFCHR;
751 		break;
752 	case '4':
753 		st.st_mode |= S_IFBLK;
754 		break;
755 	case '5':
756 		st.st_mode |= S_IFDIR;
757 		break;
758 	case '6':
759 		st.st_mode |= S_IFIFO;
760 		break;
761 	case 'g':
762 		ret = tarerofs_parse_pax_header(&tar->ios, &tar->global,
763 						st.st_size);
764 		if (ret)
765 			goto out;
766 		if (tar->global.path) {
767 			free(eh.path);
768 			eh.path = strdup(tar->global.path);
769 		}
770 		if (tar->global.link) {
771 			free(eh.link);
772 			eh.link = strdup(tar->global.link);
773 		}
774 		goto restart;
775 	case 'x':
776 		ret = tarerofs_parse_pax_header(&tar->ios, &eh, st.st_size);
777 		if (ret)
778 			goto out;
779 		goto restart;
780 	case 'L':
781 		free(eh.path);
782 		eh.path = malloc(st.st_size + 1);
783 		if (st.st_size != erofs_iostream_bread(&tar->ios, eh.path,
784 						       st.st_size))
785 			goto invalid_tar;
786 		eh.path[st.st_size] = '\0';
787 		goto restart;
788 	case 'K':
789 		free(eh.link);
790 		eh.link = malloc(st.st_size + 1);
791 		if (st.st_size > PATH_MAX || st.st_size !=
792 		    erofs_iostream_bread(&tar->ios, eh.link, st.st_size))
793 			goto invalid_tar;
794 		eh.link[st.st_size] = '\0';
795 		goto restart;
796 	default:
797 		erofs_info("unrecognized typeflag %xh @ %llu - ignoring",
798 			   th->typeflag, tar_offset);
799 		(void)erofs_iostream_lskip(&tar->ios, st.st_size);
800 		ret = 0;
801 		goto out;
802 	}
803 
804 	st.st_rdev = 0;
805 	if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) {
806 		int major, minor;
807 
808 		major = tarerofs_parsenum(th->devmajor, sizeof(th->devmajor));
809 		if (errno) {
810 			erofs_err("invalid device major @ %llu", tar_offset);
811 			goto out;
812 		}
813 
814 		minor = tarerofs_parsenum(th->devminor, sizeof(th->devminor));
815 		if (errno) {
816 			erofs_err("invalid device minor @ %llu", tar_offset);
817 			goto out;
818 		}
819 
820 		st.st_rdev = (major << 8) | (minor & 0xff) | ((minor & ~0xff) << 12);
821 	} else if (th->typeflag == '1' || th->typeflag == '2') {
822 		if (!eh.link)
823 			eh.link = strndup(th->linkname, sizeof(th->linkname));
824 	}
825 
826 	if (tar->index_mode && !tar->mapfile &&
827 	    erofs_blkoff(sbi, data_offset)) {
828 		erofs_err("invalid tar data alignment @ %llu", tar_offset);
829 		ret = -EIO;
830 		goto out;
831 	}
832 
833 	erofs_dbg("parsing %s (mode %05o)", eh.path, st.st_mode);
834 
835 	d = erofs_rebuild_get_dentry(root, eh.path, tar->aufs, &whout, &opq, true);
836 	if (IS_ERR(d)) {
837 		ret = PTR_ERR(d);
838 		goto out;
839 	}
840 
841 	if (!d) {
842 		/* some tarballs include '.' which indicates the root directory */
843 		if (!S_ISDIR(st.st_mode)) {
844 			ret = -ENOTDIR;
845 			goto out;
846 		}
847 		inode = root;
848 	} else if (opq) {
849 		DBG_BUGON(d->type == EROFS_FT_UNKNOWN);
850 		DBG_BUGON(!d->inode);
851 		ret = erofs_set_opaque_xattr(d->inode);
852 		goto out;
853 	} else if (th->typeflag == '1') {	/* hard link cases */
854 		struct erofs_dentry *d2;
855 		bool dumb;
856 
857 		if (S_ISDIR(st.st_mode)) {
858 			ret = -EISDIR;
859 			goto out;
860 		}
861 
862 		if (d->type != EROFS_FT_UNKNOWN) {
863 			tarerofs_remove_inode(d->inode);
864 			erofs_iput(d->inode);
865 		}
866 		d->inode = NULL;
867 
868 		d2 = erofs_rebuild_get_dentry(root, eh.link, tar->aufs,
869 					      &dumb, &dumb, false);
870 		if (IS_ERR(d2)) {
871 			ret = PTR_ERR(d2);
872 			goto out;
873 		}
874 		if (d2->type == EROFS_FT_UNKNOWN) {
875 			ret = -ENOENT;
876 			goto out;
877 		}
878 		if (S_ISDIR(d2->inode->i_mode)) {
879 			ret = -EISDIR;
880 			goto out;
881 		}
882 		inode = erofs_igrab(d2->inode);
883 		d->inode = inode;
884 		d->type = d2->type;
885 		++inode->i_nlink;
886 		ret = 0;
887 		goto out;
888 	} else if (d->type != EROFS_FT_UNKNOWN) {
889 		if (d->type != EROFS_FT_DIR || !S_ISDIR(st.st_mode)) {
890 			struct erofs_inode *parent = d->inode->i_parent;
891 
892 			tarerofs_remove_inode(d->inode);
893 			erofs_iput(d->inode);
894 			d->inode = parent;
895 			goto new_inode;
896 		}
897 		inode = d->inode;
898 	} else {
899 new_inode:
900 		inode = erofs_new_inode();
901 		if (IS_ERR(inode)) {
902 			ret = PTR_ERR(inode);
903 			goto out;
904 		}
905 		inode->i_parent = d->inode;
906 		d->inode = inode;
907 		d->type = erofs_mode_to_ftype(st.st_mode);
908 	}
909 
910 	if (whout) {
911 		inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFCHR;
912 		inode->u.i_rdev = EROFS_WHITEOUT_DEV;
913 		d->type = EROFS_FT_CHRDEV;
914 
915 		/*
916 		 * Mark the parent directory as copied-up to avoid exposing
917 		 * whiteouts if mounted.  See kernel commit b79e05aaa166
918 		 * ("ovl: no direct iteration for dir with origin xattr")
919 		 */
920 		inode->i_parent->whiteouts = true;
921 	} else {
922 		inode->i_mode = st.st_mode;
923 		if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
924 			inode->u.i_rdev = erofs_new_encode_dev(st.st_rdev);
925 	}
926 
927 	inode->i_srcpath = strdup(eh.path);
928 	if (!inode->i_srcpath) {
929 		ret = -ENOMEM;
930 		goto out;
931 	}
932 
933 	ret = __erofs_fill_inode(inode, &st, eh.path);
934 	if (ret)
935 		goto out;
936 	inode->i_size = st.st_size;
937 
938 	if (!S_ISDIR(inode->i_mode)) {
939 		if (S_ISLNK(inode->i_mode)) {
940 			inode->i_size = strlen(eh.link);
941 			inode->i_link = malloc(inode->i_size + 1);
942 			memcpy(inode->i_link, eh.link, inode->i_size + 1);
943 		} else if (inode->i_size) {
944 			if (tar->index_mode)
945 				ret = tarerofs_write_file_index(inode, tar,
946 								data_offset);
947 			else
948 				ret = tarerofs_write_file_data(inode, tar);
949 			if (ret)
950 				goto out;
951 		}
952 		inode->i_nlink++;
953 	} else if (!inode->i_nlink) {
954 		ret = erofs_init_empty_dir(inode);
955 		if (ret)
956 			goto out;
957 	}
958 
959 	ret = tarerofs_merge_xattrs(&eh.xattrs, &tar->global.xattrs);
960 	if (ret)
961 		goto out;
962 
963 	ret = tarerofs_apply_xattrs(inode, &eh.xattrs);
964 
965 out:
966 	if (eh.path != path)
967 		free(eh.path);
968 	free(eh.link);
969 	tarerofs_remove_xattrs(&eh.xattrs);
970 	return ret;
971 
972 invalid_tar:
973 	erofs_err("invalid tar @ %llu", tar_offset);
974 	ret = -EIO;
975 	goto out;
976 }
977