1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2013 Juniper Networks, Inc. 5 * Copyright (c) 2022-2023 Klara, Inc. 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 AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include "opt_tarfs.h" 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/buf.h> 34 #include <sys/conf.h> 35 #include <sys/fcntl.h> 36 #include <sys/libkern.h> 37 #include <sys/limits.h> 38 #include <sys/lock.h> 39 #include <sys/malloc.h> 40 #include <sys/mount.h> 41 #include <sys/mutex.h> 42 #include <sys/namei.h> 43 #include <sys/priv.h> 44 #include <sys/proc.h> 45 #include <sys/queue.h> 46 #include <sys/sbuf.h> 47 #include <sys/stat.h> 48 #include <sys/uio.h> 49 #include <sys/vnode.h> 50 51 #include <vm/vm_param.h> 52 53 #include <geom/geom.h> 54 #include <geom/geom_vfs.h> 55 56 #include <fs/tarfs/tarfs.h> 57 #include <fs/tarfs/tarfs_dbg.h> 58 59 CTASSERT(ZERO_REGION_SIZE > TARFS_BLOCKSIZE); 60 61 struct ustar_header { 62 char name[100]; /* File name */ 63 char mode[8]; /* Mode flags */ 64 char uid[8]; /* User id */ 65 char gid[8]; /* Group id */ 66 char size[12]; /* Size */ 67 char mtime[12]; /* Modified time */ 68 char checksum[8]; /* Checksum */ 69 char typeflag[1]; /* Type */ 70 char linkname[100]; /* "old format" stops here */ 71 char magic[6]; /* POSIX UStar "ustar\0" indicator */ 72 char version[2]; /* POSIX UStar version "00" */ 73 char uname[32]; /* User name */ 74 char gname[32]; /* Group name */ 75 char major[8]; /* Device major number */ 76 char minor[8]; /* Device minor number */ 77 char prefix[155]; /* Path prefix */ 78 }; 79 80 #define TAR_EOF ((off_t)-1) 81 82 #define TAR_TYPE_FILE '0' 83 #define TAR_TYPE_HARDLINK '1' 84 #define TAR_TYPE_SYMLINK '2' 85 #define TAR_TYPE_CHAR '3' 86 #define TAR_TYPE_BLOCK '4' 87 #define TAR_TYPE_DIRECTORY '5' 88 #define TAR_TYPE_FIFO '6' 89 #define TAR_TYPE_CONTIG '7' 90 #define TAR_TYPE_GLOBAL_EXTHDR 'g' 91 #define TAR_TYPE_EXTHDR 'x' 92 #define TAR_TYPE_GNU_SPARSE 'S' 93 94 #define USTAR_MAGIC (uint8_t []){ 'u', 's', 't', 'a', 'r', 0 } 95 #define USTAR_VERSION (uint8_t []){ '0', '0' } 96 #define GNUTAR_MAGIC (uint8_t []){ 'u', 's', 't', 'a', 'r', ' ' } 97 #define GNUTAR_VERSION (uint8_t []){ ' ', '\x0' } 98 99 #define DEFDIRMODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) 100 101 MALLOC_DEFINE(M_TARFSMNT, "tarfs mount", "tarfs mount structures"); 102 MALLOC_DEFINE(M_TARFSNODE, "tarfs node", "tarfs node structures"); 103 104 static vfs_mount_t tarfs_mount; 105 static vfs_unmount_t tarfs_unmount; 106 static vfs_root_t tarfs_root; 107 static vfs_statfs_t tarfs_statfs; 108 static vfs_fhtovp_t tarfs_fhtovp; 109 110 static const char *tarfs_opts[] = { 111 "as", "from", "gid", "mode", "uid", "verify", 112 NULL 113 }; 114 115 /* 116 * Reads a len-width signed octal number from strp. Returns the value. 117 * XXX Does not report errors. 118 */ 119 static int64_t 120 tarfs_str2octal(const char *strp, size_t len) 121 { 122 int64_t val; 123 size_t idx; 124 int sign; 125 126 /* 127 * Skip leading spaces or tabs. 128 * XXX why? POSIX requires numeric fields to be 0-padded. 129 */ 130 for (idx = 0; idx < len; idx++) 131 if (strp[idx] != ' ' && strp[idx] != '\t') 132 break; 133 134 if (idx == len) 135 return (0); 136 137 if (strp[idx] == '-') { 138 sign = -1; 139 idx++; 140 } else 141 sign = 1; 142 143 val = 0; 144 for (; idx < len; idx++) { 145 if (strp[idx] < '0' || strp[idx] > '7') 146 break; 147 val <<= 3; 148 val += (strp[idx] - '0'); 149 150 /* Truncate on overflow */ 151 if (val > INT64_MAX / 8) { 152 val = INT64_MAX; 153 break; 154 } 155 } 156 157 return (sign > 0) ? val : -val; 158 } 159 160 /* 161 * Reads a len-byte extended numeric value from strp. The first byte has 162 * bit 7 set to indicate the format; the remaining 7 bits + the (len - 1) 163 * bytes that follow form a big-endian signed two's complement binary 164 * number. Returns the value. XXX Does not report errors. 165 */ 166 static int64_t 167 tarfs_str2base256(const char *strp, size_t len) 168 { 169 int64_t val; 170 size_t idx; 171 172 KASSERT(strp[0] & 0x80, ("not an extended numeric value")); 173 174 /* Sign-extend the first byte */ 175 if ((strp[0] & 0x40) != 0) 176 val = (int64_t)-1; 177 else 178 val = 0; 179 val <<= 6; 180 val |= (strp[0] & 0x3f); 181 182 /* Read subsequent bytes */ 183 for (idx = 1; idx < len; idx++) { 184 val <<= 8; 185 val |= (0xff & (int64_t)strp[idx]); 186 187 /* Truncate on overflow and underflow */ 188 if (val > INT64_MAX / 256) { 189 val = INT64_MAX; 190 break; 191 } else if (val < INT64_MAX / 256) { 192 val = INT64_MIN; 193 break; 194 } 195 } 196 197 return (val); 198 } 199 200 /* 201 * Read a len-byte numeric field from strp. If bit 7 of the first byte it 202 * set, assume an extended numeric value (signed two's complement); 203 * otherwise, assume a signed octal value. 204 * 205 * XXX practically no error checking or handling 206 */ 207 static int64_t 208 tarfs_str2int64(const char *strp, size_t len) 209 { 210 211 if (len < 1) 212 return (0); 213 214 if ((strp[0] & 0x80) != 0) 215 return (tarfs_str2base256(strp, len)); 216 return (tarfs_str2octal(strp, len)); 217 } 218 219 /* 220 * Verifies the checksum of a header. Returns true if the checksum is 221 * valid, false otherwise. 222 */ 223 static boolean_t 224 tarfs_checksum(struct ustar_header *hdrp) 225 { 226 const unsigned char *ptr; 227 int64_t checksum, hdrsum; 228 size_t idx; 229 230 hdrsum = tarfs_str2int64(hdrp->checksum, sizeof(hdrp->checksum)); 231 TARFS_DPF(CHECKSUM, "%s: header checksum %lx\n", __func__, hdrsum); 232 233 checksum = 0; 234 for (ptr = (const unsigned char *)hdrp; 235 ptr < (const unsigned char *)hdrp->checksum; ptr++) 236 checksum += *ptr; 237 for (idx = 0; idx < sizeof(hdrp->checksum); idx++) 238 checksum += 0x20; 239 for (ptr = (const unsigned char *)hdrp->typeflag; 240 ptr < (const unsigned char *)(hdrp + 1); ptr++) 241 checksum += *ptr; 242 TARFS_DPF(CHECKSUM, "%s: calc unsigned checksum %lx\n", __func__, 243 checksum); 244 if (hdrsum == checksum) 245 return (true); 246 247 /* 248 * Repeat test with signed bytes, some older formats use a broken 249 * form of the calculation 250 */ 251 checksum = 0; 252 for (ptr = (const unsigned char *)hdrp; 253 ptr < (const unsigned char *)&hdrp->checksum; ptr++) 254 checksum += *((const signed char *)ptr); 255 for (idx = 0; idx < sizeof(hdrp->checksum); idx++) 256 checksum += 0x20; 257 for (ptr = (const unsigned char *)&hdrp->typeflag; 258 ptr < (const unsigned char *)(hdrp + 1); ptr++) 259 checksum += *((const signed char *)ptr); 260 TARFS_DPF(CHECKSUM, "%s: calc signed checksum %lx\n", __func__, 261 checksum); 262 if (hdrsum == checksum) 263 return (true); 264 265 return (false); 266 } 267 268 269 /* 270 * Looks up a path in the tarfs node tree. 271 * 272 * - If the path exists, stores a pointer to the corresponding tarfs_node 273 * in retnode and a pointer to its parent in retparent. 274 * 275 * - If the path does not exist, but create_dirs is true, creates ancestor 276 * directories and returns NULL in retnode and the parent in retparent. 277 * 278 * - If the path does not exist and create_dirs is false, stops at the 279 * first missing path name component. 280 * 281 * - In all cases, on return, endp and sepp point to the beginning and 282 * end, respectively, of the last-processed path name component. 283 * 284 * - Returns 0 if the node was found, ENOENT if it was not, and some other 285 * positive errno value on failure. 286 */ 287 static int 288 tarfs_lookup_path(struct tarfs_mount *tmp, char *name, size_t namelen, 289 char **endp, char **sepp, struct tarfs_node **retparent, 290 struct tarfs_node **retnode, boolean_t create_dirs) 291 { 292 struct componentname cn = { }; 293 struct tarfs_node *parent, *tnp; 294 char *sep; 295 size_t len; 296 int error; 297 boolean_t do_lookup; 298 299 MPASS(name != NULL && namelen != 0); 300 301 do_lookup = true; 302 error = 0; 303 parent = tnp = tmp->root; 304 if (tnp == NULL) 305 panic("%s: root node not yet created", __func__); 306 307 TARFS_DPF(LOOKUP, "%s: full path: %.*s\n", __func__, 308 (int)namelen, name); 309 310 sep = NULL; 311 for (;;) { 312 /* skip leading slash(es) */ 313 while (name[0] == '/' && namelen > 0) 314 name++, namelen--; 315 316 /* did we reach the end? */ 317 if (namelen == 0 || name[0] == '\0') { 318 name = do_lookup ? NULL : cn.cn_nameptr; 319 namelen = do_lookup ? 0 : cn.cn_namelen; 320 break; 321 } 322 323 /* we're not at the end, so we must be in a directory */ 324 if (tnp != NULL && tnp->type != VDIR) { 325 TARFS_DPF(LOOKUP, "%s: %.*s is not a directory\n", __func__, 326 (int)tnp->namelen, tnp->name); 327 error = ENOTDIR; 328 break; 329 } 330 331 /* locate the next separator */ 332 for (sep = name, len = 0; 333 *sep != '\0' && *sep != '/' && len < namelen; 334 sep++, len++) 335 /* nothing */ ; 336 337 /* check for . and .. */ 338 if (name[0] == '.' && len == 1) { 339 name += len; 340 namelen -= len; 341 continue; 342 } 343 if (name[0] == '.' && name[1] == '.' && len == 2) { 344 if (tnp == tmp->root) { 345 error = EINVAL; 346 break; 347 } 348 tnp = parent; 349 parent = tnp->parent; 350 cn.cn_nameptr = tnp->name; 351 cn.cn_namelen = tnp->namelen; 352 do_lookup = true; 353 TARFS_DPF(LOOKUP, "%s: back to %.*s/\n", __func__, 354 (int)tnp->namelen, tnp->name); 355 name += len; 356 namelen -= len; 357 continue; 358 } 359 360 /* create parent if necessary */ 361 if (!do_lookup) { 362 TARFS_DPF(ALLOC, "%s: creating %.*s\n", __func__, 363 (int)cn.cn_namelen, cn.cn_nameptr); 364 error = tarfs_alloc_node(tmp, cn.cn_nameptr, 365 cn.cn_namelen, VDIR, -1, 0, tmp->mtime, 0, 0, 366 DEFDIRMODE, 0, NULL, NODEV, parent, &tnp); 367 if (error != 0) 368 break; 369 } 370 371 parent = tnp; 372 tnp = NULL; 373 cn.cn_nameptr = name; 374 cn.cn_namelen = len; 375 TARFS_DPF(LOOKUP, "%s: looking up %.*s in %.*s/\n", __func__, 376 (int)cn.cn_namelen, cn.cn_nameptr, 377 (int)parent->namelen, parent->name); 378 if (do_lookup) { 379 tnp = tarfs_lookup_node(parent, NULL, &cn); 380 if (tnp == NULL) { 381 do_lookup = false; 382 if (!create_dirs) 383 break; 384 } 385 } 386 name += cn.cn_namelen; 387 namelen -= cn.cn_namelen; 388 } 389 390 TARFS_DPF(LOOKUP, "%s: parent %p node %p\n", __func__, parent, tnp); 391 392 if (retparent) 393 *retparent = parent; 394 if (retnode) 395 *retnode = tnp; 396 if (endp) { 397 if (namelen > 0) 398 *endp = name; 399 else 400 *endp = NULL; 401 } 402 if (sepp) 403 *sepp = sep; 404 return (error); 405 } 406 407 /* 408 * Frees a tarfs_mount structure and everything it references. 409 */ 410 static void 411 tarfs_free_mount(struct tarfs_mount *tmp) 412 { 413 struct mount *mp; 414 struct tarfs_node *tnp, *tnp_next; 415 416 MPASS(tmp != NULL); 417 418 TARFS_DPF(ALLOC, "%s: Freeing mount structure %p\n", __func__, tmp); 419 420 TARFS_DPF(ALLOC, "%s: freeing tarfs_node structures\n", __func__); 421 TAILQ_FOREACH_SAFE(tnp, &tmp->allnodes, entries, tnp_next) { 422 tarfs_free_node(tnp); 423 } 424 425 (void)tarfs_io_fini(tmp); 426 427 TARFS_DPF(ALLOC, "%s: deleting unr header\n", __func__); 428 delete_unrhdr(tmp->ino_unr); 429 mp = tmp->vfs; 430 mp->mnt_data = NULL; 431 432 TARFS_DPF(ALLOC, "%s: freeing structure\n", __func__); 433 free(tmp, M_TARFSMNT); 434 } 435 436 /* 437 * Processes the tar file header at block offset blknump and allocates and 438 * populates a tarfs_node structure for the file it describes. Updated 439 * blknump to point to the next unread tar file block, or TAR_EOF if EOF 440 * is reached. Returns 0 on success or EOF and a positive errno value on 441 * failure. 442 */ 443 static int 444 tarfs_alloc_one(struct tarfs_mount *tmp, off_t *blknump) 445 { 446 char block[TARFS_BLOCKSIZE]; 447 struct ustar_header *hdrp = (struct ustar_header *)block; 448 struct sbuf *namebuf = NULL; 449 char *exthdr = NULL, *name = NULL, *link = NULL; 450 off_t blknum = *blknump; 451 int64_t num; 452 int endmarker = 0; 453 char *namep, *sep; 454 struct tarfs_node *parent, *tnp; 455 size_t namelen = 0, linklen = 0, realsize = 0, sz; 456 ssize_t res; 457 dev_t rdev; 458 gid_t gid; 459 mode_t mode; 460 time_t mtime; 461 uid_t uid; 462 long major = -1, minor = -1; 463 unsigned int flags = 0; 464 int error; 465 boolean_t sparse = false; 466 467 again: 468 /* read next header */ 469 res = tarfs_io_read_buf(tmp, false, block, 470 TARFS_BLOCKSIZE * blknum, TARFS_BLOCKSIZE); 471 if (res < 0) { 472 error = -res; 473 goto bad; 474 } else if (res < TARFS_BLOCKSIZE) { 475 goto eof; 476 } 477 blknum++; 478 479 /* check for end marker */ 480 if (memcmp(block, zero_region, TARFS_BLOCKSIZE) == 0) { 481 if (endmarker++) { 482 if (exthdr != NULL) { 483 TARFS_DPF(IO, "%s: orphaned extended header at %zu\n", 484 __func__, TARFS_BLOCKSIZE * (blknum - 1)); 485 free(exthdr, M_TEMP); 486 } 487 TARFS_DPF(IO, "%s: end of archive at %zu\n", __func__, 488 TARFS_BLOCKSIZE * blknum); 489 tmp->nblocks = blknum; 490 *blknump = TAR_EOF; 491 return (0); 492 } 493 goto again; 494 } 495 496 /* verify magic */ 497 if (memcmp(hdrp->magic, USTAR_MAGIC, sizeof(USTAR_MAGIC)) == 0 && 498 memcmp(hdrp->version, USTAR_VERSION, sizeof(USTAR_VERSION)) == 0) { 499 /* POSIX */ 500 } else if (memcmp(hdrp->magic, GNUTAR_MAGIC, sizeof(GNUTAR_MAGIC)) == 0 && 501 memcmp(hdrp->magic, GNUTAR_MAGIC, sizeof(GNUTAR_MAGIC)) == 0) { 502 TARFS_DPF(ALLOC, "%s: GNU tar format at %zu\n", __func__, 503 TARFS_BLOCKSIZE * (blknum - 1)); 504 error = EFTYPE; 505 goto bad; 506 } else { 507 TARFS_DPF(ALLOC, "%s: unsupported TAR format at %zu\n", 508 __func__, TARFS_BLOCKSIZE * (blknum - 1)); 509 error = EINVAL; 510 goto bad; 511 } 512 513 /* verify checksum */ 514 if (!tarfs_checksum(hdrp)) { 515 TARFS_DPF(ALLOC, "%s: header checksum failed at %zu\n", 516 __func__, TARFS_BLOCKSIZE * (blknum - 1)); 517 error = EINVAL; 518 goto bad; 519 } 520 521 /* get standard attributes */ 522 num = tarfs_str2int64(hdrp->mode, sizeof(hdrp->mode)); 523 if (num < 0 || num > (S_IFMT|ALLPERMS)) { 524 TARFS_DPF(ALLOC, "%s: invalid file mode at %zu\n", 525 __func__, TARFS_BLOCKSIZE * (blknum - 1)); 526 mode = S_IRUSR; 527 } else { 528 mode = num & ALLPERMS; 529 } 530 num = tarfs_str2int64(hdrp->uid, sizeof(hdrp->uid)); 531 if (num < 0 || num > UID_MAX) { 532 TARFS_DPF(ALLOC, "%s: UID out of range at %zu\n", 533 __func__, TARFS_BLOCKSIZE * (blknum - 1)); 534 uid = tmp->root->uid; 535 mode &= ~S_ISUID; 536 } else { 537 uid = num; 538 } 539 num = tarfs_str2int64(hdrp->gid, sizeof(hdrp->gid)); 540 if (num < 0 || num > GID_MAX) { 541 TARFS_DPF(ALLOC, "%s: GID out of range at %zu\n", 542 __func__, TARFS_BLOCKSIZE * (blknum - 1)); 543 gid = tmp->root->gid; 544 mode &= ~S_ISGID; 545 } else { 546 gid = num; 547 } 548 num = tarfs_str2int64(hdrp->size, sizeof(hdrp->size)); 549 if (num < 0) { 550 TARFS_DPF(ALLOC, "%s: negative size at %zu\n", 551 __func__, TARFS_BLOCKSIZE * (blknum - 1)); 552 error = EINVAL; 553 goto bad; 554 } else { 555 sz = num; 556 } 557 mtime = tarfs_str2int64(hdrp->mtime, sizeof(hdrp->mtime)); 558 rdev = NODEV; 559 TARFS_DPF(ALLOC, "%s: [%c] %zu @%jd %o %d:%d\n", __func__, 560 hdrp->typeflag[0], sz, (intmax_t)mtime, mode, uid, gid); 561 562 /* extended header? */ 563 if (hdrp->typeflag[0] == TAR_TYPE_GLOBAL_EXTHDR) { 564 printf("%s: unsupported global extended header at %zu\n", 565 __func__, (size_t)(TARFS_BLOCKSIZE * (blknum - 1))); 566 error = EFTYPE; 567 goto bad; 568 } 569 if (hdrp->typeflag[0] == TAR_TYPE_EXTHDR) { 570 if (exthdr != NULL) { 571 TARFS_DPF(IO, "%s: multiple extended headers at %zu\n", 572 __func__, TARFS_BLOCKSIZE * (blknum - 1)); 573 error = EFTYPE; 574 goto bad; 575 } 576 /* read the contents of the exthdr */ 577 TARFS_DPF(ALLOC, "%s: %zu-byte extended header at %zd\n", 578 __func__, sz, TARFS_BLOCKSIZE * (blknum - 1)); 579 exthdr = malloc(sz, M_TEMP, M_WAITOK); 580 res = tarfs_io_read_buf(tmp, false, exthdr, 581 TARFS_BLOCKSIZE * blknum, sz); 582 if (res < 0) { 583 error = -res; 584 goto bad; 585 } 586 if (res < sz) { 587 goto eof; 588 } 589 blknum += TARFS_SZ2BLKS(res); 590 /* XXX TODO: refactor this parser */ 591 char *line = exthdr; 592 while (line < exthdr + sz) { 593 char *eol, *key, *value, *sep; 594 size_t len = strtoul(line, &sep, 10); 595 if (len == 0 || sep == line || *sep != ' ') { 596 TARFS_DPF(ALLOC, "%s: exthdr syntax error\n", 597 __func__); 598 error = EINVAL; 599 goto bad; 600 } 601 if (line + len > exthdr + sz) { 602 TARFS_DPF(ALLOC, "%s: exthdr overflow\n", 603 __func__); 604 error = EINVAL; 605 goto bad; 606 } 607 eol = line + len - 1; 608 *eol = '\0'; 609 line += len; 610 key = sep + 1; 611 sep = strchr(key, '='); 612 if (sep == NULL) { 613 TARFS_DPF(ALLOC, "%s: exthdr syntax error\n", 614 __func__); 615 error = EINVAL; 616 goto bad; 617 } 618 *sep = '\0'; 619 value = sep + 1; 620 TARFS_DPF(ALLOC, "%s: exthdr %s=%s\n", __func__, 621 key, value); 622 if (strcmp(key, "linkpath") == 0) { 623 link = value; 624 linklen = eol - value; 625 } else if (strcmp(key, "GNU.sparse.major") == 0) { 626 sparse = true; 627 major = strtol(value, &sep, 10); 628 if (sep != eol) { 629 printf("exthdr syntax error\n"); 630 error = EINVAL; 631 goto bad; 632 } 633 } else if (strcmp(key, "GNU.sparse.minor") == 0) { 634 sparse = true; 635 minor = strtol(value, &sep, 10); 636 if (sep != eol) { 637 printf("exthdr syntax error\n"); 638 error = EINVAL; 639 goto bad; 640 } 641 } else if (strcmp(key, "GNU.sparse.name") == 0) { 642 sparse = true; 643 name = value; 644 namelen = eol - value; 645 if (namelen == 0) { 646 printf("exthdr syntax error\n"); 647 error = EINVAL; 648 goto bad; 649 } 650 } else if (strcmp(key, "GNU.sparse.realsize") == 0) { 651 sparse = true; 652 realsize = strtoul(value, &sep, 10); 653 if (sep != eol) { 654 printf("exthdr syntax error\n"); 655 error = EINVAL; 656 goto bad; 657 } 658 } else if (strcmp(key, "SCHILY.fflags") == 0) { 659 flags |= tarfs_strtofflags(value, &sep); 660 if (sep != eol) { 661 printf("exthdr syntax error\n"); 662 error = EINVAL; 663 goto bad; 664 } 665 } 666 } 667 goto again; 668 } 669 670 /* sparse file consistency checks */ 671 if (sparse) { 672 TARFS_DPF(ALLOC, "%s: %s: sparse %ld.%ld (%zu bytes)\n", __func__, 673 name, major, minor, realsize); 674 if (major != 1 || minor != 0 || name == NULL || realsize == 0 || 675 hdrp->typeflag[0] != TAR_TYPE_FILE) { 676 TARFS_DPF(ALLOC, "%s: invalid sparse format\n", __func__); 677 error = EINVAL; 678 goto bad; 679 } 680 } 681 682 /* file name */ 683 if (name == NULL) { 684 if (hdrp->prefix[0] != '\0') { 685 namebuf = sbuf_new_auto(); 686 sbuf_printf(namebuf, "%.*s/%.*s", 687 (int)sizeof(hdrp->prefix), hdrp->prefix, 688 (int)sizeof(hdrp->name), hdrp->name); 689 sbuf_finish(namebuf); 690 name = sbuf_data(namebuf); 691 namelen = sbuf_len(namebuf); 692 } else { 693 name = hdrp->name; 694 namelen = strnlen(hdrp->name, sizeof(hdrp->name)); 695 } 696 } 697 698 error = tarfs_lookup_path(tmp, name, namelen, &namep, 699 &sep, &parent, &tnp, true); 700 if (error != 0) { 701 TARFS_DPF(ALLOC, "%s: failed to look up %.*s\n", __func__, 702 (int)namelen, name); 703 error = EINVAL; 704 goto bad; 705 } 706 if (tnp != NULL) { 707 if (hdrp->typeflag[0] == TAR_TYPE_DIRECTORY) { 708 /* XXX set attributes? */ 709 goto skip; 710 } 711 TARFS_DPF(ALLOC, "%s: duplicate file %.*s\n", __func__, 712 (int)namelen, name); 713 error = EINVAL; 714 goto bad; 715 } 716 switch (hdrp->typeflag[0]) { 717 case TAR_TYPE_DIRECTORY: 718 error = tarfs_alloc_node(tmp, namep, sep - namep, VDIR, 719 0, 0, mtime, uid, gid, mode, flags, NULL, 0, 720 parent, &tnp); 721 break; 722 case TAR_TYPE_FILE: 723 error = tarfs_alloc_node(tmp, namep, sep - namep, VREG, 724 blknum * TARFS_BLOCKSIZE, sz, mtime, uid, gid, mode, 725 flags, NULL, 0, parent, &tnp); 726 if (error == 0 && sparse) { 727 error = tarfs_load_blockmap(tnp, realsize); 728 } 729 break; 730 case TAR_TYPE_HARDLINK: 731 if (link == NULL) { 732 link = hdrp->linkname; 733 linklen = strnlen(link, sizeof(hdrp->linkname)); 734 } 735 error = tarfs_alloc_node(tmp, namep, sep - namep, VREG, 736 0, 0, 0, 0, 0, 0, 0, NULL, 0, parent, &tnp); 737 if (error != 0) { 738 goto bad; 739 } 740 error = tarfs_lookup_path(tmp, link, linklen, NULL, 741 NULL, NULL, &tnp->other, false); 742 if (tnp->other == NULL || 743 tnp->other->type != VREG || 744 tnp->other->other != NULL) { 745 TARFS_DPF(ALLOC, "%s: %.*s: dead hard link to %.*s\n", 746 __func__, (int)namelen, name, (int)linklen, link); 747 error = EINVAL; 748 goto bad; 749 } 750 tnp->other->nlink++; 751 break; 752 case TAR_TYPE_SYMLINK: 753 if (link == NULL) { 754 link = hdrp->linkname; 755 linklen = strnlen(link, sizeof(hdrp->linkname)); 756 } 757 error = tarfs_alloc_node(tmp, namep, sep - namep, VLNK, 758 0, linklen, mtime, uid, gid, mode, flags, link, 0, 759 parent, &tnp); 760 break; 761 case TAR_TYPE_BLOCK: 762 major = tarfs_str2int64(hdrp->major, sizeof(hdrp->major)); 763 minor = tarfs_str2int64(hdrp->minor, sizeof(hdrp->minor)); 764 rdev = makedev(major, minor); 765 error = tarfs_alloc_node(tmp, namep, sep - namep, VBLK, 766 0, 0, mtime, uid, gid, mode, flags, NULL, rdev, 767 parent, &tnp); 768 break; 769 case TAR_TYPE_CHAR: 770 major = tarfs_str2int64(hdrp->major, sizeof(hdrp->major)); 771 minor = tarfs_str2int64(hdrp->minor, sizeof(hdrp->minor)); 772 rdev = makedev(major, minor); 773 error = tarfs_alloc_node(tmp, namep, sep - namep, VCHR, 774 0, 0, mtime, uid, gid, mode, flags, NULL, rdev, 775 parent, &tnp); 776 break; 777 default: 778 TARFS_DPF(ALLOC, "%s: unsupported type %c for %.*s\n", 779 __func__, hdrp->typeflag[0], (int)namelen, name); 780 error = EINVAL; 781 break; 782 } 783 if (error != 0) 784 goto bad; 785 786 skip: 787 blknum += TARFS_SZ2BLKS(sz); 788 tmp->nblocks = blknum; 789 *blknump = blknum; 790 if (exthdr != NULL) { 791 free(exthdr, M_TEMP); 792 } 793 if (namebuf != NULL) { 794 sbuf_delete(namebuf); 795 } 796 return (0); 797 eof: 798 TARFS_DPF(IO, "%s: premature end of file\n", __func__); 799 error = EIO; 800 goto bad; 801 bad: 802 if (exthdr != NULL) { 803 free(exthdr, M_TEMP); 804 } 805 if (namebuf != NULL) { 806 sbuf_delete(namebuf); 807 } 808 return (error); 809 } 810 811 /* 812 * Allocates and populates the metadata structures for the tar file 813 * referenced by vp. On success, a pointer to the tarfs_mount structure 814 * is stored in tmpp. Returns 0 on success or a positive errno value on 815 * failure. 816 */ 817 static int 818 tarfs_alloc_mount(struct mount *mp, struct vnode *vp, 819 uid_t root_uid, gid_t root_gid, mode_t root_mode, 820 struct tarfs_mount **tmpp) 821 { 822 struct vattr va; 823 struct thread *td = curthread; 824 struct tarfs_mount *tmp; 825 struct tarfs_node *root; 826 off_t blknum; 827 time_t mtime; 828 int error; 829 830 KASSERT(tmpp != NULL, ("tarfs mount return is NULL")); 831 ASSERT_VOP_LOCKED(vp, __func__); 832 833 tmp = NULL; 834 835 TARFS_DPF(ALLOC, "%s: Allocating tarfs mount structure for vp %p\n", 836 __func__, vp); 837 838 /* Get source metadata */ 839 error = VOP_GETATTR(vp, &va, td->td_ucred); 840 if (error != 0) { 841 return (error); 842 } 843 VOP_UNLOCK(vp); 844 mtime = va.va_mtime.tv_sec; 845 846 /* Allocate and initialize tarfs mount structure */ 847 tmp = malloc(sizeof(*tmp), M_TARFSMNT, M_WAITOK | M_ZERO); 848 TARFS_DPF(ALLOC, "%s: Allocated mount structure\n", __func__); 849 mp->mnt_data = tmp; 850 851 mtx_init(&tmp->allnode_lock, "tarfs allnode lock", NULL, 852 MTX_DEF); 853 TAILQ_INIT(&tmp->allnodes); 854 tmp->ino_unr = new_unrhdr(TARFS_MININO, INT_MAX, &tmp->allnode_lock); 855 tmp->vp = vp; 856 tmp->vfs = mp; 857 tmp->mtime = mtime; 858 859 /* 860 * XXX The decompression layer passes everything through the 861 * buffer cache, and the buffer cache wants to know our blocksize, 862 * but mnt_stat normally isn't populated until after we return, so 863 * we have to cheat a bit. 864 */ 865 tmp->iosize = 1U << tarfs_ioshift; 866 mp->mnt_stat.f_iosize = tmp->iosize; 867 868 /* Initialize decompression layer */ 869 error = tarfs_io_init(tmp); 870 if (error != 0) 871 goto bad; 872 873 error = tarfs_alloc_node(tmp, NULL, 0, VDIR, 0, 0, mtime, root_uid, 874 root_gid, root_mode & ALLPERMS, 0, NULL, NODEV, NULL, &root); 875 if (error != 0 || root == NULL) 876 goto bad; 877 tmp->root = root; 878 879 blknum = 0; 880 do { 881 if ((error = tarfs_alloc_one(tmp, &blknum)) != 0) { 882 goto bad; 883 } 884 } while (blknum != TAR_EOF); 885 886 *tmpp = tmp; 887 888 TARFS_DPF(ALLOC, "%s: pfsmnt_root %p\n", __func__, tmp->root); 889 return (0); 890 891 bad: 892 tarfs_free_mount(tmp); 893 return (error); 894 } 895 896 /* 897 * VFS Operations. 898 */ 899 900 static int 901 tarfs_mount(struct mount *mp) 902 { 903 struct nameidata nd; 904 struct vattr va; 905 struct tarfs_mount *tmp = NULL; 906 struct thread *td = curthread; 907 struct vnode *vp; 908 char *as, *from; 909 uid_t root_uid; 910 gid_t root_gid; 911 mode_t root_mode; 912 int error, flags, aslen, len; 913 914 if (mp->mnt_flag & MNT_UPDATE) 915 return (EOPNOTSUPP); 916 917 if (vfs_filteropt(mp->mnt_optnew, tarfs_opts)) 918 return (EINVAL); 919 920 vn_lock(mp->mnt_vnodecovered, LK_SHARED | LK_RETRY); 921 error = VOP_GETATTR(mp->mnt_vnodecovered, &va, mp->mnt_cred); 922 VOP_UNLOCK(mp->mnt_vnodecovered); 923 if (error) 924 return (error); 925 926 if (mp->mnt_cred->cr_ruid != 0 || 927 vfs_scanopt(mp->mnt_optnew, "gid", "%d", &root_gid) != 1) 928 root_gid = va.va_gid; 929 if (mp->mnt_cred->cr_ruid != 0 || 930 vfs_scanopt(mp->mnt_optnew, "uid", "%d", &root_uid) != 1) 931 root_uid = va.va_uid; 932 if (mp->mnt_cred->cr_ruid != 0 || 933 vfs_scanopt(mp->mnt_optnew, "mode", "%ho", &root_mode) != 1) 934 root_mode = va.va_mode; 935 936 error = vfs_getopt(mp->mnt_optnew, "from", (void **)&from, &len); 937 if (error != 0 || from[len - 1] != '\0') 938 return (EINVAL); 939 error = vfs_getopt(mp->mnt_optnew, "as", (void **)&as, &aslen); 940 if (error != 0 || as[aslen - 1] != '\0') 941 as = from; 942 943 /* Find the source tarball */ 944 TARFS_DPF(FS, "%s(%s%s%s, uid=%u, gid=%u, mode=%o)\n", __func__, 945 from, (as != from) ? " as " : "", (as != from) ? as : "", 946 root_uid, root_gid, root_mode); 947 flags = FREAD; 948 if (vfs_flagopt(mp->mnt_optnew, "verify", NULL, 0)) { 949 flags |= O_VERIFY; 950 } 951 NDINIT(&nd, LOOKUP, ISOPEN | FOLLOW | LOCKLEAF, UIO_SYSSPACE, from); 952 error = namei(&nd); 953 if (error != 0) 954 return (error); 955 NDFREE_PNBUF(&nd); 956 vp = nd.ni_vp; 957 TARFS_DPF(FS, "%s: N: hold %u use %u lock 0x%x\n", __func__, 958 vp->v_holdcnt, vp->v_usecount, VOP_ISLOCKED(vp)); 959 /* vp is now held and locked */ 960 961 /* Open the source tarball */ 962 error = vn_open_vnode(vp, flags, td->td_ucred, td, NULL); 963 if (error != 0) { 964 TARFS_DPF(FS, "%s: failed to open %s: %d\n", __func__, 965 from, error); 966 vput(vp); 967 goto bad; 968 } 969 TARFS_DPF(FS, "%s: O: hold %u use %u lock 0x%x\n", __func__, 970 vp->v_holdcnt, vp->v_usecount, VOP_ISLOCKED(vp)); 971 if (vp->v_type != VREG) { 972 TARFS_DPF(FS, "%s: not a regular file\n", __func__); 973 error = EOPNOTSUPP; 974 goto bad_open_locked; 975 } 976 error = priv_check(td, PRIV_VFS_MOUNT_PERM); 977 if (error != 0) { 978 TARFS_DPF(FS, "%s: not permitted to mount\n", __func__); 979 goto bad_open_locked; 980 } 981 if (flags & O_VERIFY) { 982 mp->mnt_flag |= MNT_VERIFIED; 983 } 984 985 /* Allocate the tarfs mount */ 986 error = tarfs_alloc_mount(mp, vp, root_uid, root_gid, root_mode, &tmp); 987 /* vp is now held but unlocked */ 988 if (error != 0) { 989 TARFS_DPF(FS, "%s: failed to mount %s: %d\n", __func__, 990 from, error); 991 goto bad_open_unlocked; 992 } 993 TARFS_DPF(FS, "%s: M: hold %u use %u lock 0x%x\n", __func__, 994 vp->v_holdcnt, vp->v_usecount, VOP_ISLOCKED(vp)); 995 996 /* Unconditionally mount as read-only */ 997 MNT_ILOCK(mp); 998 mp->mnt_flag |= (MNT_LOCAL | MNT_RDONLY); 999 MNT_IUNLOCK(mp); 1000 1001 vfs_getnewfsid(mp); 1002 vfs_mountedfrom(mp, as); 1003 TARFS_DPF(FS, "%s: success\n", __func__); 1004 1005 return (0); 1006 1007 bad_open_locked: 1008 /* vp must be held and locked */ 1009 TARFS_DPF(FS, "%s: L: hold %u use %u lock 0x%x\n", __func__, 1010 vp->v_holdcnt, vp->v_usecount, VOP_ISLOCKED(vp)); 1011 VOP_UNLOCK(vp); 1012 bad_open_unlocked: 1013 /* vp must be held and unlocked */ 1014 TARFS_DPF(FS, "%s: E: hold %u use %u lock 0x%x\n", __func__, 1015 vp->v_holdcnt, vp->v_usecount, VOP_ISLOCKED(vp)); 1016 (void)vn_close(vp, flags, td->td_ucred, td); 1017 bad: 1018 /* vp must be released and unlocked */ 1019 TARFS_DPF(FS, "%s: X: hold %u use %u lock 0x%x\n", __func__, 1020 vp->v_holdcnt, vp->v_usecount, VOP_ISLOCKED(vp)); 1021 return (error); 1022 } 1023 1024 /* 1025 * Unmounts a tarfs filesystem. 1026 */ 1027 static int 1028 tarfs_unmount(struct mount *mp, int mntflags) 1029 { 1030 struct thread *td = curthread; 1031 struct tarfs_mount *tmp; 1032 struct vnode *vp; 1033 int error; 1034 int flags = 0; 1035 1036 TARFS_DPF(FS, "%s: Unmounting %p\n", __func__, mp); 1037 1038 /* Handle forced unmounts */ 1039 if (mntflags & MNT_FORCE) 1040 flags |= FORCECLOSE; 1041 1042 /* Finalize all pending I/O */ 1043 error = vflush(mp, 0, flags, curthread); 1044 if (error != 0) 1045 return (error); 1046 tmp = MP_TO_TARFS_MOUNT(mp); 1047 vp = tmp->vp; 1048 1049 MPASS(vp != NULL); 1050 TARFS_DPF(FS, "%s: U: hold %u use %u lock 0x%x\n", __func__, 1051 vp->v_holdcnt, vp->v_usecount, VOP_ISLOCKED(vp)); 1052 vn_close(vp, FREAD, td->td_ucred, td); 1053 TARFS_DPF(FS, "%s: C: hold %u use %u lock 0x%x\n", __func__, 1054 vp->v_holdcnt, vp->v_usecount, VOP_ISLOCKED(vp)); 1055 tarfs_free_mount(tmp); 1056 1057 return (0); 1058 } 1059 1060 /* 1061 * Gets the root of a tarfs filesystem. Returns 0 on success or a 1062 * positive errno value on failure. 1063 */ 1064 static int 1065 tarfs_root(struct mount *mp, int flags, struct vnode **vpp) 1066 { 1067 struct vnode *nvp; 1068 int error; 1069 1070 TARFS_DPF(FS, "%s: Getting root vnode\n", __func__); 1071 1072 error = VFS_VGET(mp, TARFS_ROOTINO, LK_EXCLUSIVE, &nvp); 1073 if (error != 0) 1074 return (error); 1075 1076 nvp->v_vflag |= VV_ROOT; 1077 *vpp = nvp; 1078 return (0); 1079 } 1080 1081 /* 1082 * Gets statistics for a tarfs filesystem. Returns 0. 1083 */ 1084 static int 1085 tarfs_statfs(struct mount *mp, struct statfs *sbp) 1086 { 1087 struct tarfs_mount *tmp; 1088 1089 tmp = MP_TO_TARFS_MOUNT(mp); 1090 1091 sbp->f_bsize = TARFS_BLOCKSIZE; 1092 sbp->f_iosize = tmp->iosize; 1093 sbp->f_blocks = tmp->nblocks; 1094 sbp->f_bfree = 0; 1095 sbp->f_bavail = 0; 1096 sbp->f_files = tmp->nfiles; 1097 sbp->f_ffree = 0; 1098 1099 return (0); 1100 } 1101 1102 /* 1103 * Gets a vnode for the given inode. On success, a pointer to the vnode 1104 * is stored in vpp. Returns 0 on success or a positive errno value on 1105 * failure. 1106 */ 1107 static int 1108 tarfs_vget(struct mount *mp, ino_t ino, int lkflags, struct vnode **vpp) 1109 { 1110 struct tarfs_mount *tmp; 1111 struct tarfs_node *tnp; 1112 struct thread *td; 1113 struct vnode *vp; 1114 int error; 1115 1116 TARFS_DPF(FS, "%s: mp %p, ino %lu, lkflags %d\n", __func__, mp, ino, 1117 lkflags); 1118 1119 td = curthread; 1120 error = vfs_hash_get(mp, ino, lkflags, td, vpp, NULL, NULL); 1121 if (error != 0) 1122 return (error); 1123 1124 if (*vpp != NULL) { 1125 TARFS_DPF(FS, "%s: found hashed vnode %p\n", __func__, *vpp); 1126 return (error); 1127 } 1128 1129 TARFS_DPF(FS, "%s: no hashed vnode for inode %lu\n", __func__, ino); 1130 1131 tmp = MP_TO_TARFS_MOUNT(mp); 1132 1133 if (ino == TARFS_ZIOINO) { 1134 error = vget(tmp->znode, lkflags); 1135 if (error != 0) 1136 return (error); 1137 *vpp = tmp->znode; 1138 return (0); 1139 } 1140 1141 /* XXX Should use hash instead? */ 1142 TAILQ_FOREACH(tnp, &tmp->allnodes, entries) { 1143 if (tnp->ino == ino) 1144 break; 1145 } 1146 TARFS_DPF(FS, "%s: search of all nodes found %p\n", __func__, tnp); 1147 if (tnp == NULL) 1148 return (ENOENT); 1149 1150 (void)getnewvnode("tarfs", mp, &tarfs_vnodeops, &vp); 1151 TARFS_DPF(FS, "%s: allocated vnode\n", __func__); 1152 vp->v_data = tnp; 1153 vp->v_type = tnp->type; 1154 tnp->vnode = vp; 1155 1156 lockmgr(vp->v_vnlock, lkflags, NULL); 1157 error = insmntque(vp, mp); 1158 if (error != 0) 1159 goto bad; 1160 TARFS_DPF(FS, "%s: inserting entry into VFS hash\n", __func__); 1161 error = vfs_hash_insert(vp, ino, lkflags, td, vpp, NULL, NULL); 1162 if (error != 0 || *vpp != NULL) 1163 return (error); 1164 1165 vn_set_state(vp, VSTATE_CONSTRUCTED); 1166 *vpp = vp; 1167 return (0); 1168 1169 bad: 1170 *vpp = NULLVP; 1171 return (error); 1172 } 1173 1174 static int 1175 tarfs_fhtovp(struct mount *mp, struct fid *fhp, int flags, struct vnode **vpp) 1176 { 1177 struct tarfs_node *tnp; 1178 struct tarfs_fid *tfp; 1179 struct vnode *nvp; 1180 int error; 1181 1182 tfp = (struct tarfs_fid *)fhp; 1183 MP_TO_TARFS_MOUNT(mp); 1184 if (tfp->ino < TARFS_ROOTINO || tfp->ino > INT_MAX) 1185 return (ESTALE); 1186 1187 error = VFS_VGET(mp, tfp->ino, LK_EXCLUSIVE, &nvp); 1188 if (error != 0) { 1189 *vpp = NULLVP; 1190 return (error); 1191 } 1192 tnp = VP_TO_TARFS_NODE(nvp); 1193 if (tnp->mode == 0 || 1194 tnp->gen != tfp->gen || 1195 tnp->nlink <= 0) { 1196 vput(nvp); 1197 *vpp = NULLVP; 1198 return (ESTALE); 1199 } 1200 *vpp = nvp; 1201 return (0); 1202 } 1203 1204 static struct vfsops tarfs_vfsops = { 1205 .vfs_fhtovp = tarfs_fhtovp, 1206 .vfs_mount = tarfs_mount, 1207 .vfs_root = tarfs_root, 1208 .vfs_statfs = tarfs_statfs, 1209 .vfs_unmount = tarfs_unmount, 1210 .vfs_vget = tarfs_vget, 1211 }; 1212 VFS_SET(tarfs_vfsops, tarfs, VFCF_READONLY); 1213 MODULE_VERSION(tarfs, 1); 1214 MODULE_DEPEND(tarfs, xz, 1, 1, 1); 1215