1 /*- 2 * Copyright (c) 2007-2014, Juniper Networks, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include "stand.h" 31 32 #include <sys/stat.h> 33 #include <sys/stdint.h> 34 #include <string.h> 35 #include <zlib.h> 36 37 #ifdef PKGFS_DEBUG 38 #define DBG(x) printf x 39 #else 40 #define DBG(x) 41 #endif 42 43 static int pkg_open(const char *, struct open_file *); 44 static int pkg_close(struct open_file *); 45 static int pkg_read(struct open_file *, void *, size_t, size_t *); 46 static off_t pkg_seek(struct open_file *, off_t, int); 47 static int pkg_stat(struct open_file *, struct stat *); 48 static int pkg_readdir(struct open_file *, struct dirent *); 49 50 struct fs_ops pkgfs_fsops = { 51 "pkg", 52 pkg_open, 53 pkg_close, 54 pkg_read, 55 null_write, 56 pkg_seek, 57 pkg_stat, 58 pkg_readdir 59 }; 60 61 #define PKG_BUFSIZE 512 62 #define PKG_MAXCACHESZ 4096 63 64 #define PKG_FILEEXT ".tgz" 65 66 /* 67 * Layout of POSIX 'ustar' header. 68 */ 69 struct ustar_hdr { 70 char ut_name[100]; 71 char ut_mode[8]; 72 char ut_uid[8]; 73 char ut_gid[8]; 74 char ut_size[12]; 75 char ut_mtime[12]; 76 char ut_checksum[8]; 77 char ut_typeflag[1]; 78 char ut_linkname[100]; 79 char ut_magic[6]; /* For POSIX: "ustar\0" */ 80 char ut_version[2]; /* For POSIX: "00" */ 81 char ut_uname[32]; 82 char ut_gname[32]; 83 char ut_rdevmajor[8]; 84 char ut_rdevminor[8]; 85 union { 86 struct { 87 char prefix[155]; 88 } posix; 89 struct { 90 char atime[12]; 91 char ctime[12]; 92 char offset[12]; 93 char longnames[4]; 94 char unused[1]; 95 struct gnu_sparse { 96 char offset[12]; 97 char numbytes[12]; 98 } sparse[4]; 99 char isextended[1]; 100 char realsize[12]; 101 } gnu; 102 } u; 103 u_char __padding[12]; 104 }; 105 106 struct package; 107 108 struct tarfile 109 { 110 struct package *tf_pkg; 111 struct tarfile *tf_next; 112 struct ustar_hdr tf_hdr; 113 off_t tf_ofs; 114 off_t tf_size; 115 off_t tf_fp; 116 size_t tf_cachesz; 117 void *tf_cache; 118 }; 119 120 struct package 121 { 122 struct package *pkg_chain; 123 int pkg_fd; 124 off_t pkg_ofs; 125 z_stream pkg_zs; 126 struct tarfile *pkg_first; 127 struct tarfile *pkg_last; 128 u_char pkg_buf[PKG_BUFSIZE]; 129 }; 130 131 static struct package *package = NULL; 132 133 static int new_package(int, struct package **); 134 135 void 136 pkgfs_cleanup(void) 137 { 138 struct package *chain; 139 struct tarfile *tf, *tfn; 140 141 while (package != NULL) { 142 inflateEnd(&package->pkg_zs); 143 close(package->pkg_fd); 144 145 tf = package->pkg_first; 146 while (tf != NULL) { 147 tfn = tf->tf_next; 148 if (tf->tf_cachesz > 0) 149 free(tf->tf_cache); 150 free(tf); 151 tf = tfn; 152 } 153 154 chain = package->pkg_chain; 155 free(package); 156 package = chain; 157 } 158 } 159 160 int 161 pkgfs_init(const char *pkgname, struct fs_ops *proto) 162 { 163 struct package *pkg; 164 int error, fd; 165 166 if (proto != &pkgfs_fsops) 167 pkgfs_cleanup(); 168 169 exclusive_file_system = proto; 170 171 fd = open(pkgname, O_RDONLY); 172 173 exclusive_file_system = NULL; 174 175 if (fd == -1) 176 return (errno); 177 178 error = new_package(fd, &pkg); 179 if (error) { 180 close(fd); 181 return (error); 182 } 183 184 if (pkg == NULL) 185 return (EDOOFUS); 186 187 pkg->pkg_chain = package; 188 package = pkg; 189 exclusive_file_system = &pkgfs_fsops; 190 return (0); 191 } 192 193 static int get_mode(struct tarfile *); 194 static int get_zipped(struct package *, void *, size_t); 195 static int new_package(int, struct package **); 196 static struct tarfile *scan_tarfile(struct package *, struct tarfile *); 197 198 static int 199 pkg_open(const char *fn, struct open_file *f) 200 { 201 struct tarfile *tf; 202 203 if (fn == NULL || f == NULL) 204 return (EINVAL); 205 206 if (package == NULL) 207 return (ENXIO); 208 209 /* 210 * We can only read from a package, so reject request to open 211 * for write-only or read-write. 212 */ 213 if (f->f_flags != F_READ) 214 return (EPERM); 215 216 /* 217 * Scan the file headers for the named file. We stop scanning 218 * at the first filename that has the .pkg extension. This is 219 * a package within a package. We assume we have all the files 220 * we need up-front and without having to dig within nested 221 * packages. 222 * 223 * Note that we preserve streaming properties as much as possible. 224 */ 225 while (*fn == '/') 226 fn++; 227 228 /* 229 * Allow opening of the root directory for use by readdir() 230 * to support listing files in the package. 231 */ 232 if (*fn == '\0') { 233 f->f_fsdata = NULL; 234 return (0); 235 } 236 237 tf = scan_tarfile(package, NULL); 238 while (tf != NULL) { 239 if (strcmp(fn, tf->tf_hdr.ut_name) == 0) { 240 f->f_fsdata = tf; 241 tf->tf_fp = 0; /* Reset the file pointer. */ 242 return (0); 243 } 244 tf = scan_tarfile(package, tf); 245 } 246 return (errno); 247 } 248 249 static int 250 pkg_close(struct open_file *f) 251 { 252 struct tarfile *tf; 253 254 tf = (struct tarfile *)f->f_fsdata; 255 if (tf == NULL) 256 return (0); 257 258 /* 259 * Free up the cache if we read all of the file. 260 */ 261 if (tf->tf_fp == tf->tf_size && tf->tf_cachesz > 0) { 262 free(tf->tf_cache); 263 tf->tf_cachesz = 0; 264 } 265 return (0); 266 } 267 268 static int 269 pkg_read(struct open_file *f, void *buf, size_t size, size_t *res) 270 { 271 struct tarfile *tf; 272 char *p; 273 off_t fp; 274 size_t sz; 275 276 tf = (struct tarfile *)f->f_fsdata; 277 if (tf == NULL) { 278 if (res != NULL) 279 *res = size; 280 return (EBADF); 281 } 282 283 fp = tf->tf_fp; 284 p = buf; 285 sz = 0; 286 while (size > 0) { 287 sz = tf->tf_size - fp; 288 if (fp < tf->tf_cachesz && tf->tf_cachesz < tf->tf_size) 289 sz = tf->tf_cachesz - fp; 290 if (size < sz) 291 sz = size; 292 if (sz == 0) 293 break; 294 295 if (fp < tf->tf_cachesz) { 296 /* Satisfy the request from cache. */ 297 memcpy(p, tf->tf_cache + fp, sz); 298 fp += sz; 299 p += sz; 300 size -= sz; 301 continue; 302 } 303 304 if (get_zipped(tf->tf_pkg, p, sz) == -1) { 305 sz = -1; 306 break; 307 } 308 309 fp += sz; 310 p += sz; 311 size -= sz; 312 313 if (tf->tf_cachesz != 0) 314 continue; 315 316 tf->tf_cachesz = (sz <= PKG_MAXCACHESZ) ? sz : PKG_MAXCACHESZ; 317 tf->tf_cache = malloc(tf->tf_cachesz); 318 if (tf->tf_cache != NULL) 319 memcpy(tf->tf_cache, buf, tf->tf_cachesz); 320 else 321 tf->tf_cachesz = 0; 322 } 323 324 tf->tf_fp = fp; 325 if (res != NULL) 326 *res = size; 327 return ((sz == -1) ? errno : 0); 328 } 329 330 static off_t 331 pkg_seek(struct open_file *f, off_t ofs, int whence) 332 { 333 char buf[512]; 334 struct tarfile *tf; 335 off_t delta; 336 size_t sz, res; 337 int error; 338 339 tf = (struct tarfile *)f->f_fsdata; 340 if (tf == NULL) { 341 errno = EBADF; 342 return (-1); 343 } 344 345 switch (whence) { 346 case SEEK_SET: 347 delta = ofs - tf->tf_fp; 348 break; 349 case SEEK_CUR: 350 delta = ofs; 351 break; 352 case SEEK_END: 353 delta = tf->tf_size - tf->tf_fp + ofs; 354 break; 355 default: 356 errno = EINVAL; 357 return (-1); 358 } 359 360 if (delta < 0) { 361 DBG(("%s: negative file seek (%jd)\n", __func__, 362 (intmax_t)delta)); 363 errno = ESPIPE; 364 return (-1); 365 } 366 367 while (delta > 0 && tf->tf_fp < tf->tf_size) { 368 sz = (delta > sizeof(buf)) ? sizeof(buf) : delta; 369 error = pkg_read(f, buf, sz, &res); 370 if (error != 0) { 371 errno = error; 372 return (-1); 373 } 374 delta -= sz - res; 375 } 376 377 return (tf->tf_fp); 378 } 379 380 static int 381 pkg_stat(struct open_file *f, struct stat *sb) 382 { 383 struct tarfile *tf; 384 385 tf = (struct tarfile *)f->f_fsdata; 386 if (tf == NULL) 387 return (EBADF); 388 memset(sb, 0, sizeof(*sb)); 389 sb->st_mode = get_mode(tf); 390 sb->st_size = tf->tf_size; 391 sb->st_blocks = (tf->tf_size + 511) / 512; 392 return (0); 393 } 394 395 static int 396 pkg_readdir(struct open_file *f, struct dirent *d) 397 { 398 struct tarfile *tf; 399 400 tf = (struct tarfile *)f->f_fsdata; 401 if (tf != NULL) 402 return (EBADF); 403 404 tf = scan_tarfile(package, NULL); 405 if (tf == NULL) 406 return (ENOENT); 407 408 d->d_fileno = 0; 409 d->d_reclen = sizeof(*d); 410 d->d_type = DT_REG; 411 memcpy(d->d_name, tf->tf_hdr.ut_name, sizeof(d->d_name)); 412 return (0); 413 } 414 415 /* 416 * Low-level support functions. 417 */ 418 419 static int 420 get_byte(struct package *pkg, off_t *op) 421 { 422 int c; 423 424 if (pkg->pkg_zs.avail_in == 0) { 425 c = read(pkg->pkg_fd, pkg->pkg_buf, PKG_BUFSIZE); 426 if (c <= 0) 427 return (-1); 428 pkg->pkg_zs.avail_in = c; 429 pkg->pkg_zs.next_in = pkg->pkg_buf; 430 } 431 432 c = *pkg->pkg_zs.next_in; 433 pkg->pkg_zs.next_in++; 434 pkg->pkg_zs.avail_in--; 435 (*op)++; 436 return (c); 437 } 438 439 static int 440 get_zipped(struct package *pkg, void *buf, size_t bufsz) 441 { 442 int c; 443 444 pkg->pkg_zs.next_out = buf; 445 pkg->pkg_zs.avail_out = bufsz; 446 447 while (pkg->pkg_zs.avail_out) { 448 if (pkg->pkg_zs.avail_in == 0) { 449 c = read(pkg->pkg_fd, pkg->pkg_buf, PKG_BUFSIZE); 450 if (c <= 0) { 451 errno = EIO; 452 return (-1); 453 } 454 pkg->pkg_zs.avail_in = c; 455 pkg->pkg_zs.next_in = pkg->pkg_buf; 456 } 457 458 c = inflate(&pkg->pkg_zs, Z_SYNC_FLUSH); 459 if (c != Z_OK && c != Z_STREAM_END) { 460 errno = EIO; 461 return (-1); 462 } 463 } 464 465 pkg->pkg_ofs += bufsz; 466 return (0); 467 } 468 469 static int 470 cache_data(struct tarfile *tf) 471 { 472 struct package *pkg; 473 size_t sz; 474 475 if (tf == NULL) { 476 DBG(("%s: no file to cache data for?\n", __func__)); 477 errno = EINVAL; 478 return (-1); 479 } 480 481 pkg = tf->tf_pkg; 482 if (pkg == NULL) { 483 DBG(("%s: no package associated with file?\n", __func__)); 484 errno = EINVAL; 485 return (-1); 486 } 487 488 if (tf->tf_ofs != pkg->pkg_ofs) { 489 DBG(("%s: caching after partial read of file %s?\n", 490 __func__, tf->tf_hdr.ut_name)); 491 errno = EINVAL; 492 return (-1); 493 } 494 495 /* We don't cache everything... */ 496 if (tf->tf_size > PKG_MAXCACHESZ) { 497 errno = ENOMEM; 498 return (-1); 499 } 500 501 /* All files are padded to a multiple of 512 bytes. */ 502 sz = (tf->tf_size + 0x1ff) & ~0x1ff; 503 504 tf->tf_cache = malloc(sz); 505 if (tf->tf_cache == NULL) { 506 DBG(("%s: could not allocate %d bytes\n", __func__, (int)sz)); 507 errno = ENOMEM; 508 return (-1); 509 } 510 511 tf->tf_cachesz = sz; 512 return (get_zipped(pkg, tf->tf_cache, sz)); 513 } 514 515 /* 516 * Note that this implementation does not (and should not!) obey 517 * locale settings; you cannot simply substitute strtol here, since 518 * it does obey locale. 519 */ 520 static off_t 521 pkg_atol8(const char *p, unsigned char_cnt) 522 { 523 int64_t l, limit, last_digit_limit; 524 int digit, sign, base; 525 526 base = 8; 527 limit = INT64_MAX / base; 528 last_digit_limit = INT64_MAX % base; 529 530 while (*p == ' ' || *p == '\t') 531 p++; 532 if (*p == '-') { 533 sign = -1; 534 p++; 535 } else 536 sign = 1; 537 538 l = 0; 539 digit = *p - '0'; 540 while (digit >= 0 && digit < base && char_cnt-- > 0) { 541 if (l>limit || (l == limit && digit > last_digit_limit)) { 542 l = UINT64_MAX; /* Truncate on overflow. */ 543 break; 544 } 545 l = (l * base) + digit; 546 digit = *++p - '0'; 547 } 548 return (sign < 0) ? -l : l; 549 } 550 551 /* 552 * Parse a base-256 integer. This is just a straight signed binary 553 * value in big-endian order, except that the high-order bit is 554 * ignored. Remember that "int64_t" may or may not be exactly 64 555 * bits; the implementation here tries to avoid making any assumptions 556 * about the actual size of an int64_t. It does assume we're using 557 * twos-complement arithmetic, though. 558 */ 559 static int64_t 560 pkg_atol256(const char *_p, unsigned char_cnt) 561 { 562 int64_t l, upper_limit, lower_limit; 563 const unsigned char *p = (const unsigned char *)_p; 564 565 upper_limit = INT64_MAX / 256; 566 lower_limit = INT64_MIN / 256; 567 568 /* Pad with 1 or 0 bits, depending on sign. */ 569 if ((0x40 & *p) == 0x40) 570 l = (int64_t)-1; 571 else 572 l = 0; 573 l = (l << 6) | (0x3f & *p++); 574 while (--char_cnt > 0) { 575 if (l > upper_limit) { 576 l = INT64_MAX; /* Truncate on overflow */ 577 break; 578 } else if (l < lower_limit) { 579 l = INT64_MIN; 580 break; 581 } 582 l = (l << 8) | (0xff & (int64_t)*p++); 583 } 584 return (l); 585 } 586 587 static off_t 588 pkg_atol(const char *p, unsigned char_cnt) 589 { 590 /* 591 * Technically, GNU pkg considers a field to be in base-256 592 * only if the first byte is 0xff or 0x80. 593 */ 594 if (*p & 0x80) 595 return (pkg_atol256(p, char_cnt)); 596 return (pkg_atol8(p, char_cnt)); 597 } 598 599 static int 600 get_mode(struct tarfile *tf) 601 { 602 return (pkg_atol(tf->tf_hdr.ut_mode, sizeof(tf->tf_hdr.ut_mode))); 603 } 604 605 /* GZip flag byte */ 606 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ 607 #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ 608 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ 609 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ 610 #define COMMENT 0x10 /* bit 4 set: file comment present */ 611 #define RESERVED 0xE0 /* bits 5..7: reserved */ 612 613 static int 614 new_package(int fd, struct package **pp) 615 { 616 struct package *pkg; 617 off_t ofs; 618 int flags, i, error; 619 620 pkg = malloc(sizeof(*pkg)); 621 if (pkg == NULL) 622 return (ENOMEM); 623 624 bzero(pkg, sizeof(*pkg)); 625 pkg->pkg_fd = fd; 626 627 /* 628 * Parse the header. 629 */ 630 error = EFTYPE; 631 ofs = 0; 632 633 /* Check megic. */ 634 if (get_byte(pkg, &ofs) != 0x1f || get_byte(pkg, &ofs) != 0x8b) 635 goto fail; 636 /* Check method. */ 637 if (get_byte(pkg, &ofs) != Z_DEFLATED) 638 goto fail; 639 /* Check flags. */ 640 flags = get_byte(pkg, &ofs); 641 if (flags & RESERVED) 642 goto fail; 643 644 /* Skip time, xflags and OS code. */ 645 for (i = 0; i < 6; i++) { 646 if (get_byte(pkg, &ofs) == -1) 647 goto fail; 648 } 649 650 /* Skip extra field. */ 651 if (flags & EXTRA_FIELD) { 652 i = (get_byte(pkg, &ofs) & 0xff) | 653 ((get_byte(pkg, &ofs) << 8) & 0xff); 654 while (i-- > 0) { 655 if (get_byte(pkg, &ofs) == -1) 656 goto fail; 657 } 658 } 659 660 /* Skip original file name. */ 661 if (flags & ORIG_NAME) { 662 do { 663 i = get_byte(pkg, &ofs); 664 } while (i != 0 && i != -1); 665 if (i == -1) 666 goto fail; 667 } 668 669 /* Print the comment if it's there. */ 670 if (flags & COMMENT) { 671 while (1) { 672 i = get_byte(pkg, &ofs); 673 if (i == -1) 674 goto fail; 675 if (i == 0) 676 break; 677 putchar(i); 678 } 679 } 680 681 /* Skip the CRC. */ 682 if (flags & HEAD_CRC) { 683 if (get_byte(pkg, &ofs) == -1) 684 goto fail; 685 if (get_byte(pkg, &ofs) == -1) 686 goto fail; 687 } 688 689 /* 690 * Done parsing the ZIP header. Spkgt the inflation engine. 691 */ 692 error = inflateInit2(&pkg->pkg_zs, -15); 693 if (error != Z_OK) 694 goto fail; 695 696 *pp = pkg; 697 return (0); 698 699 fail: 700 free(pkg); 701 return (error); 702 } 703 704 static struct tarfile * 705 scan_tarfile(struct package *pkg, struct tarfile *last) 706 { 707 char buf[512]; 708 struct tarfile *cur; 709 off_t ofs; 710 size_t sz; 711 712 cur = (last != NULL) ? last->tf_next : pkg->pkg_first; 713 if (cur == NULL) { 714 ofs = (last != NULL) ? last->tf_ofs + last->tf_size : 715 pkg->pkg_ofs; 716 ofs = (ofs + 0x1ff) & ~0x1ff; 717 718 /* Check if we've reached EOF. */ 719 if (ofs < pkg->pkg_ofs) { 720 errno = ENOSPC; 721 return (NULL); 722 } 723 724 if (ofs != pkg->pkg_ofs) { 725 if (last != NULL && pkg->pkg_ofs == last->tf_ofs) { 726 if (cache_data(last) == -1) 727 return (NULL); 728 } else { 729 sz = ofs - pkg->pkg_ofs; 730 while (sz != 0) { 731 if (sz > sizeof(buf)) 732 sz = sizeof(buf); 733 if (get_zipped(pkg, buf, sz) == -1) 734 return (NULL); 735 sz = ofs - pkg->pkg_ofs; 736 } 737 } 738 } 739 740 cur = malloc(sizeof(*cur)); 741 if (cur == NULL) 742 return (NULL); 743 memset(cur, 0, sizeof(*cur)); 744 cur->tf_pkg = pkg; 745 746 while (1) { 747 if (get_zipped(pkg, &cur->tf_hdr, 748 sizeof(cur->tf_hdr)) == -1) { 749 free(cur); 750 return (NULL); 751 } 752 753 /* 754 * There are always 2 empty blocks appended to 755 * a PKG. It marks the end of the archive. 756 */ 757 if (strncmp(cur->tf_hdr.ut_magic, "ustar", 5) != 0) { 758 free(cur); 759 errno = ENOSPC; 760 return (NULL); 761 } 762 763 cur->tf_ofs = pkg->pkg_ofs; 764 cur->tf_size = pkg_atol(cur->tf_hdr.ut_size, 765 sizeof(cur->tf_hdr.ut_size)); 766 767 if (cur->tf_hdr.ut_name[0] != '+') 768 break; 769 770 /* 771 * Skip package meta-files. 772 */ 773 ofs = cur->tf_ofs + cur->tf_size; 774 ofs = (ofs + 0x1ff) & ~0x1ff; 775 while (pkg->pkg_ofs < ofs) { 776 if (get_zipped(pkg, buf, sizeof(buf)) == -1) { 777 free(cur); 778 return (NULL); 779 } 780 } 781 } 782 783 if (last != NULL) 784 last->tf_next = cur; 785 else 786 pkg->pkg_first = cur; 787 pkg->pkg_last = cur; 788 } 789 790 return (cur); 791 } 792