1 /* 2 * linux/fs/isofs/rock.c 3 * 4 * (C) 1992, 1993 Eric Youngdale 5 * 6 * Rock Ridge Extensions to iso9660 7 */ 8 9 #include <linux/slab.h> 10 #include <linux/pagemap.h> 11 12 #include "isofs.h" 13 #include "rock.h" 14 15 /* 16 * These functions are designed to read the system areas of a directory record 17 * and extract relevant information. There are different functions provided 18 * depending upon what information we need at the time. One function fills 19 * out an inode structure, a second one extracts a filename, a third one 20 * returns a symbolic link name, and a fourth one returns the extent number 21 * for the file. 22 */ 23 24 #define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */ 25 26 struct rock_state { 27 void *buffer; 28 unsigned char *chr; 29 int len; 30 int cont_size; 31 int cont_extent; 32 int cont_offset; 33 struct inode *inode; 34 }; 35 36 /* 37 * This is a way of ensuring that we have something in the system 38 * use fields that is compatible with Rock Ridge. Return zero on success. 39 */ 40 41 static int check_sp(struct rock_ridge *rr, struct inode *inode) 42 { 43 if (rr->u.SP.magic[0] != 0xbe) 44 return -1; 45 if (rr->u.SP.magic[1] != 0xef) 46 return -1; 47 ISOFS_SB(inode->i_sb)->s_rock_offset = rr->u.SP.skip; 48 return 0; 49 } 50 51 static void setup_rock_ridge(struct iso_directory_record *de, 52 struct inode *inode, struct rock_state *rs) 53 { 54 rs->len = sizeof(struct iso_directory_record) + de->name_len[0]; 55 if (rs->len & 1) 56 (rs->len)++; 57 rs->chr = (unsigned char *)de + rs->len; 58 rs->len = *((unsigned char *)de) - rs->len; 59 if (rs->len < 0) 60 rs->len = 0; 61 62 if (ISOFS_SB(inode->i_sb)->s_rock_offset != -1) { 63 rs->len -= ISOFS_SB(inode->i_sb)->s_rock_offset; 64 rs->chr += ISOFS_SB(inode->i_sb)->s_rock_offset; 65 if (rs->len < 0) 66 rs->len = 0; 67 } 68 } 69 70 static void init_rock_state(struct rock_state *rs, struct inode *inode) 71 { 72 memset(rs, 0, sizeof(*rs)); 73 rs->inode = inode; 74 } 75 76 /* 77 * Returns 0 if the caller should continue scanning, 1 if the scan must end 78 * and -ve on error. 79 */ 80 static int rock_continue(struct rock_state *rs) 81 { 82 int ret = 1; 83 int blocksize = 1 << rs->inode->i_blkbits; 84 const int min_de_size = offsetof(struct rock_ridge, u); 85 86 kfree(rs->buffer); 87 rs->buffer = NULL; 88 89 if ((unsigned)rs->cont_offset > blocksize - min_de_size || 90 (unsigned)rs->cont_size > blocksize || 91 (unsigned)(rs->cont_offset + rs->cont_size) > blocksize) { 92 printk(KERN_NOTICE "rock: corrupted directory entry. " 93 "extent=%d, offset=%d, size=%d\n", 94 rs->cont_extent, rs->cont_offset, rs->cont_size); 95 ret = -EIO; 96 goto out; 97 } 98 99 if (rs->cont_extent) { 100 struct buffer_head *bh; 101 102 rs->buffer = kmalloc(rs->cont_size, GFP_KERNEL); 103 if (!rs->buffer) { 104 ret = -ENOMEM; 105 goto out; 106 } 107 ret = -EIO; 108 bh = sb_bread(rs->inode->i_sb, rs->cont_extent); 109 if (bh) { 110 memcpy(rs->buffer, bh->b_data + rs->cont_offset, 111 rs->cont_size); 112 put_bh(bh); 113 rs->chr = rs->buffer; 114 rs->len = rs->cont_size; 115 rs->cont_extent = 0; 116 rs->cont_size = 0; 117 rs->cont_offset = 0; 118 return 0; 119 } 120 printk("Unable to read rock-ridge attributes\n"); 121 } 122 out: 123 kfree(rs->buffer); 124 rs->buffer = NULL; 125 return ret; 126 } 127 128 /* 129 * We think there's a record of type `sig' at rs->chr. Parse the signature 130 * and make sure that there's really room for a record of that type. 131 */ 132 static int rock_check_overflow(struct rock_state *rs, int sig) 133 { 134 int len; 135 136 switch (sig) { 137 case SIG('S', 'P'): 138 len = sizeof(struct SU_SP_s); 139 break; 140 case SIG('C', 'E'): 141 len = sizeof(struct SU_CE_s); 142 break; 143 case SIG('E', 'R'): 144 len = sizeof(struct SU_ER_s); 145 break; 146 case SIG('R', 'R'): 147 len = sizeof(struct RR_RR_s); 148 break; 149 case SIG('P', 'X'): 150 len = sizeof(struct RR_PX_s); 151 break; 152 case SIG('P', 'N'): 153 len = sizeof(struct RR_PN_s); 154 break; 155 case SIG('S', 'L'): 156 len = sizeof(struct RR_SL_s); 157 break; 158 case SIG('N', 'M'): 159 len = sizeof(struct RR_NM_s); 160 break; 161 case SIG('C', 'L'): 162 len = sizeof(struct RR_CL_s); 163 break; 164 case SIG('P', 'L'): 165 len = sizeof(struct RR_PL_s); 166 break; 167 case SIG('T', 'F'): 168 len = sizeof(struct RR_TF_s); 169 break; 170 case SIG('Z', 'F'): 171 len = sizeof(struct RR_ZF_s); 172 break; 173 default: 174 len = 0; 175 break; 176 } 177 len += offsetof(struct rock_ridge, u); 178 if (len > rs->len) { 179 printk(KERN_NOTICE "rock: directory entry would overflow " 180 "storage\n"); 181 printk(KERN_NOTICE "rock: sig=0x%02x, size=%d, remaining=%d\n", 182 sig, len, rs->len); 183 return -EIO; 184 } 185 return 0; 186 } 187 188 /* 189 * return length of name field; 0: not found, -1: to be ignored 190 */ 191 int get_rock_ridge_filename(struct iso_directory_record *de, 192 char *retname, struct inode *inode) 193 { 194 struct rock_state rs; 195 struct rock_ridge *rr; 196 int sig; 197 int retnamlen = 0; 198 int truncate = 0; 199 int ret = 0; 200 201 if (!ISOFS_SB(inode->i_sb)->s_rock) 202 return 0; 203 *retname = 0; 204 205 init_rock_state(&rs, inode); 206 setup_rock_ridge(de, inode, &rs); 207 repeat: 208 209 while (rs.len > 2) { /* There may be one byte for padding somewhere */ 210 rr = (struct rock_ridge *)rs.chr; 211 /* 212 * Ignore rock ridge info if rr->len is out of range, but 213 * don't return -EIO because that would make the file 214 * invisible. 215 */ 216 if (rr->len < 3) 217 goto out; /* Something got screwed up here */ 218 sig = isonum_721(rs.chr); 219 if (rock_check_overflow(&rs, sig)) 220 goto eio; 221 rs.chr += rr->len; 222 rs.len -= rr->len; 223 /* 224 * As above, just ignore the rock ridge info if rr->len 225 * is bogus. 226 */ 227 if (rs.len < 0) 228 goto out; /* Something got screwed up here */ 229 230 switch (sig) { 231 case SIG('R', 'R'): 232 if ((rr->u.RR.flags[0] & RR_NM) == 0) 233 goto out; 234 break; 235 case SIG('S', 'P'): 236 if (check_sp(rr, inode)) 237 goto out; 238 break; 239 case SIG('C', 'E'): 240 rs.cont_extent = isonum_733(rr->u.CE.extent); 241 rs.cont_offset = isonum_733(rr->u.CE.offset); 242 rs.cont_size = isonum_733(rr->u.CE.size); 243 break; 244 case SIG('N', 'M'): 245 if (truncate) 246 break; 247 if (rr->len < 5) 248 break; 249 /* 250 * If the flags are 2 or 4, this indicates '.' or '..'. 251 * We don't want to do anything with this, because it 252 * screws up the code that calls us. We don't really 253 * care anyways, since we can just use the non-RR 254 * name. 255 */ 256 if (rr->u.NM.flags & 6) 257 break; 258 259 if (rr->u.NM.flags & ~1) { 260 printk("Unsupported NM flag settings (%d)\n", 261 rr->u.NM.flags); 262 break; 263 } 264 if ((strlen(retname) + rr->len - 5) >= 254) { 265 truncate = 1; 266 break; 267 } 268 strncat(retname, rr->u.NM.name, rr->len - 5); 269 retnamlen += rr->len - 5; 270 break; 271 case SIG('R', 'E'): 272 kfree(rs.buffer); 273 return -1; 274 default: 275 break; 276 } 277 } 278 ret = rock_continue(&rs); 279 if (ret == 0) 280 goto repeat; 281 if (ret == 1) 282 return retnamlen; /* If 0, this file did not have a NM field */ 283 out: 284 kfree(rs.buffer); 285 return ret; 286 eio: 287 ret = -EIO; 288 goto out; 289 } 290 291 static int 292 parse_rock_ridge_inode_internal(struct iso_directory_record *de, 293 struct inode *inode, int regard_xa) 294 { 295 int symlink_len = 0; 296 int cnt, sig; 297 struct inode *reloc; 298 struct rock_ridge *rr; 299 int rootflag; 300 struct rock_state rs; 301 int ret = 0; 302 303 if (!ISOFS_SB(inode->i_sb)->s_rock) 304 return 0; 305 306 init_rock_state(&rs, inode); 307 setup_rock_ridge(de, inode, &rs); 308 if (regard_xa) { 309 rs.chr += 14; 310 rs.len -= 14; 311 if (rs.len < 0) 312 rs.len = 0; 313 } 314 315 repeat: 316 while (rs.len > 2) { /* There may be one byte for padding somewhere */ 317 rr = (struct rock_ridge *)rs.chr; 318 /* 319 * Ignore rock ridge info if rr->len is out of range, but 320 * don't return -EIO because that would make the file 321 * invisible. 322 */ 323 if (rr->len < 3) 324 goto out; /* Something got screwed up here */ 325 sig = isonum_721(rs.chr); 326 if (rock_check_overflow(&rs, sig)) 327 goto eio; 328 rs.chr += rr->len; 329 rs.len -= rr->len; 330 /* 331 * As above, just ignore the rock ridge info if rr->len 332 * is bogus. 333 */ 334 if (rs.len < 0) 335 goto out; /* Something got screwed up here */ 336 337 switch (sig) { 338 #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ 339 case SIG('R', 'R'): 340 if ((rr->u.RR.flags[0] & 341 (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) 342 goto out; 343 break; 344 #endif 345 case SIG('S', 'P'): 346 if (check_sp(rr, inode)) 347 goto out; 348 break; 349 case SIG('C', 'E'): 350 rs.cont_extent = isonum_733(rr->u.CE.extent); 351 rs.cont_offset = isonum_733(rr->u.CE.offset); 352 rs.cont_size = isonum_733(rr->u.CE.size); 353 break; 354 case SIG('E', 'R'): 355 ISOFS_SB(inode->i_sb)->s_rock = 1; 356 printk(KERN_DEBUG "ISO 9660 Extensions: "); 357 { 358 int p; 359 for (p = 0; p < rr->u.ER.len_id; p++) 360 printk("%c", rr->u.ER.data[p]); 361 } 362 printk("\n"); 363 break; 364 case SIG('P', 'X'): 365 inode->i_mode = isonum_733(rr->u.PX.mode); 366 set_nlink(inode, isonum_733(rr->u.PX.n_links)); 367 i_uid_write(inode, isonum_733(rr->u.PX.uid)); 368 i_gid_write(inode, isonum_733(rr->u.PX.gid)); 369 break; 370 case SIG('P', 'N'): 371 { 372 int high, low; 373 high = isonum_733(rr->u.PN.dev_high); 374 low = isonum_733(rr->u.PN.dev_low); 375 /* 376 * The Rock Ridge standard specifies that if 377 * sizeof(dev_t) <= 4, then the high field is 378 * unused, and the device number is completely 379 * stored in the low field. Some writers may 380 * ignore this subtlety, 381 * and as a result we test to see if the entire 382 * device number is 383 * stored in the low field, and use that. 384 */ 385 if ((low & ~0xff) && high == 0) { 386 inode->i_rdev = 387 MKDEV(low >> 8, low & 0xff); 388 } else { 389 inode->i_rdev = 390 MKDEV(high, low); 391 } 392 } 393 break; 394 case SIG('T', 'F'): 395 /* 396 * Some RRIP writers incorrectly place ctime in the 397 * TF_CREATE field. Try to handle this correctly for 398 * either case. 399 */ 400 /* Rock ridge never appears on a High Sierra disk */ 401 cnt = 0; 402 if (rr->u.TF.flags & TF_CREATE) { 403 inode->i_ctime.tv_sec = 404 iso_date(rr->u.TF.times[cnt++].time, 405 0); 406 inode->i_ctime.tv_nsec = 0; 407 } 408 if (rr->u.TF.flags & TF_MODIFY) { 409 inode->i_mtime.tv_sec = 410 iso_date(rr->u.TF.times[cnt++].time, 411 0); 412 inode->i_mtime.tv_nsec = 0; 413 } 414 if (rr->u.TF.flags & TF_ACCESS) { 415 inode->i_atime.tv_sec = 416 iso_date(rr->u.TF.times[cnt++].time, 417 0); 418 inode->i_atime.tv_nsec = 0; 419 } 420 if (rr->u.TF.flags & TF_ATTRIBUTES) { 421 inode->i_ctime.tv_sec = 422 iso_date(rr->u.TF.times[cnt++].time, 423 0); 424 inode->i_ctime.tv_nsec = 0; 425 } 426 break; 427 case SIG('S', 'L'): 428 { 429 int slen; 430 struct SL_component *slp; 431 struct SL_component *oldslp; 432 slen = rr->len - 5; 433 slp = &rr->u.SL.link; 434 inode->i_size = symlink_len; 435 while (slen > 1) { 436 rootflag = 0; 437 switch (slp->flags & ~1) { 438 case 0: 439 inode->i_size += 440 slp->len; 441 break; 442 case 2: 443 inode->i_size += 1; 444 break; 445 case 4: 446 inode->i_size += 2; 447 break; 448 case 8: 449 rootflag = 1; 450 inode->i_size += 1; 451 break; 452 default: 453 printk("Symlink component flag " 454 "not implemented\n"); 455 } 456 slen -= slp->len + 2; 457 oldslp = slp; 458 slp = (struct SL_component *) 459 (((char *)slp) + slp->len + 2); 460 461 if (slen < 2) { 462 if (((rr->u.SL. 463 flags & 1) != 0) 464 && 465 ((oldslp-> 466 flags & 1) == 0)) 467 inode->i_size += 468 1; 469 break; 470 } 471 472 /* 473 * If this component record isn't 474 * continued, then append a '/'. 475 */ 476 if (!rootflag 477 && (oldslp->flags & 1) == 0) 478 inode->i_size += 1; 479 } 480 } 481 symlink_len = inode->i_size; 482 break; 483 case SIG('R', 'E'): 484 printk(KERN_WARNING "Attempt to read inode for " 485 "relocated directory\n"); 486 goto out; 487 case SIG('C', 'L'): 488 ISOFS_I(inode)->i_first_extent = 489 isonum_733(rr->u.CL.location); 490 reloc = 491 isofs_iget(inode->i_sb, 492 ISOFS_I(inode)->i_first_extent, 493 0); 494 if (IS_ERR(reloc)) { 495 ret = PTR_ERR(reloc); 496 goto out; 497 } 498 inode->i_mode = reloc->i_mode; 499 set_nlink(inode, reloc->i_nlink); 500 inode->i_uid = reloc->i_uid; 501 inode->i_gid = reloc->i_gid; 502 inode->i_rdev = reloc->i_rdev; 503 inode->i_size = reloc->i_size; 504 inode->i_blocks = reloc->i_blocks; 505 inode->i_atime = reloc->i_atime; 506 inode->i_ctime = reloc->i_ctime; 507 inode->i_mtime = reloc->i_mtime; 508 iput(reloc); 509 break; 510 #ifdef CONFIG_ZISOFS 511 case SIG('Z', 'F'): { 512 int algo; 513 514 if (ISOFS_SB(inode->i_sb)->s_nocompress) 515 break; 516 algo = isonum_721(rr->u.ZF.algorithm); 517 if (algo == SIG('p', 'z')) { 518 int block_shift = 519 isonum_711(&rr->u.ZF.parms[1]); 520 if (block_shift > 17) { 521 printk(KERN_WARNING "isofs: " 522 "Can't handle ZF block " 523 "size of 2^%d\n", 524 block_shift); 525 } else { 526 /* 527 * Note: we don't change 528 * i_blocks here 529 */ 530 ISOFS_I(inode)->i_file_format = 531 isofs_file_compressed; 532 /* 533 * Parameters to compression 534 * algorithm (header size, 535 * block size) 536 */ 537 ISOFS_I(inode)->i_format_parm[0] = 538 isonum_711(&rr->u.ZF.parms[0]); 539 ISOFS_I(inode)->i_format_parm[1] = 540 isonum_711(&rr->u.ZF.parms[1]); 541 inode->i_size = 542 isonum_733(rr->u.ZF. 543 real_size); 544 } 545 } else { 546 printk(KERN_WARNING 547 "isofs: Unknown ZF compression " 548 "algorithm: %c%c\n", 549 rr->u.ZF.algorithm[0], 550 rr->u.ZF.algorithm[1]); 551 } 552 break; 553 } 554 #endif 555 default: 556 break; 557 } 558 } 559 ret = rock_continue(&rs); 560 if (ret == 0) 561 goto repeat; 562 if (ret == 1) 563 ret = 0; 564 out: 565 kfree(rs.buffer); 566 return ret; 567 eio: 568 ret = -EIO; 569 goto out; 570 } 571 572 static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) 573 { 574 int slen; 575 int rootflag; 576 struct SL_component *oldslp; 577 struct SL_component *slp; 578 slen = rr->len - 5; 579 slp = &rr->u.SL.link; 580 while (slen > 1) { 581 rootflag = 0; 582 switch (slp->flags & ~1) { 583 case 0: 584 if (slp->len > plimit - rpnt) 585 return NULL; 586 memcpy(rpnt, slp->text, slp->len); 587 rpnt += slp->len; 588 break; 589 case 2: 590 if (rpnt >= plimit) 591 return NULL; 592 *rpnt++ = '.'; 593 break; 594 case 4: 595 if (2 > plimit - rpnt) 596 return NULL; 597 *rpnt++ = '.'; 598 *rpnt++ = '.'; 599 break; 600 case 8: 601 if (rpnt >= plimit) 602 return NULL; 603 rootflag = 1; 604 *rpnt++ = '/'; 605 break; 606 default: 607 printk("Symlink component flag not implemented (%d)\n", 608 slp->flags); 609 } 610 slen -= slp->len + 2; 611 oldslp = slp; 612 slp = (struct SL_component *)((char *)slp + slp->len + 2); 613 614 if (slen < 2) { 615 /* 616 * If there is another SL record, and this component 617 * record isn't continued, then add a slash. 618 */ 619 if ((!rootflag) && (rr->u.SL.flags & 1) && 620 !(oldslp->flags & 1)) { 621 if (rpnt >= plimit) 622 return NULL; 623 *rpnt++ = '/'; 624 } 625 break; 626 } 627 628 /* 629 * If this component record isn't continued, then append a '/'. 630 */ 631 if (!rootflag && !(oldslp->flags & 1)) { 632 if (rpnt >= plimit) 633 return NULL; 634 *rpnt++ = '/'; 635 } 636 } 637 return rpnt; 638 } 639 640 int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode) 641 { 642 int result = parse_rock_ridge_inode_internal(de, inode, 0); 643 644 /* 645 * if rockridge flag was reset and we didn't look for attributes 646 * behind eventual XA attributes, have a look there 647 */ 648 if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1) 649 && (ISOFS_SB(inode->i_sb)->s_rock == 2)) { 650 result = parse_rock_ridge_inode_internal(de, inode, 14); 651 } 652 return result; 653 } 654 655 /* 656 * readpage() for symlinks: reads symlink contents into the page and either 657 * makes it uptodate and returns 0 or returns error (-EIO) 658 */ 659 static int rock_ridge_symlink_readpage(struct file *file, struct page *page) 660 { 661 struct inode *inode = page->mapping->host; 662 struct iso_inode_info *ei = ISOFS_I(inode); 663 struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb); 664 char *link = kmap(page); 665 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); 666 struct buffer_head *bh; 667 char *rpnt = link; 668 unsigned char *pnt; 669 struct iso_directory_record *raw_de; 670 unsigned long block, offset; 671 int sig; 672 struct rock_ridge *rr; 673 struct rock_state rs; 674 int ret; 675 676 if (!sbi->s_rock) 677 goto error; 678 679 init_rock_state(&rs, inode); 680 block = ei->i_iget5_block; 681 bh = sb_bread(inode->i_sb, block); 682 if (!bh) 683 goto out_noread; 684 685 offset = ei->i_iget5_offset; 686 pnt = (unsigned char *)bh->b_data + offset; 687 688 raw_de = (struct iso_directory_record *)pnt; 689 690 /* 691 * If we go past the end of the buffer, there is some sort of error. 692 */ 693 if (offset + *pnt > bufsize) 694 goto out_bad_span; 695 696 /* 697 * Now test for possible Rock Ridge extensions which will override 698 * some of these numbers in the inode structure. 699 */ 700 701 setup_rock_ridge(raw_de, inode, &rs); 702 703 repeat: 704 while (rs.len > 2) { /* There may be one byte for padding somewhere */ 705 rr = (struct rock_ridge *)rs.chr; 706 if (rr->len < 3) 707 goto out; /* Something got screwed up here */ 708 sig = isonum_721(rs.chr); 709 if (rock_check_overflow(&rs, sig)) 710 goto out; 711 rs.chr += rr->len; 712 rs.len -= rr->len; 713 if (rs.len < 0) 714 goto out; /* corrupted isofs */ 715 716 switch (sig) { 717 case SIG('R', 'R'): 718 if ((rr->u.RR.flags[0] & RR_SL) == 0) 719 goto out; 720 break; 721 case SIG('S', 'P'): 722 if (check_sp(rr, inode)) 723 goto out; 724 break; 725 case SIG('S', 'L'): 726 rpnt = get_symlink_chunk(rpnt, rr, 727 link + (PAGE_SIZE - 1)); 728 if (rpnt == NULL) 729 goto out; 730 break; 731 case SIG('C', 'E'): 732 /* This tells is if there is a continuation record */ 733 rs.cont_extent = isonum_733(rr->u.CE.extent); 734 rs.cont_offset = isonum_733(rr->u.CE.offset); 735 rs.cont_size = isonum_733(rr->u.CE.size); 736 default: 737 break; 738 } 739 } 740 ret = rock_continue(&rs); 741 if (ret == 0) 742 goto repeat; 743 if (ret < 0) 744 goto fail; 745 746 if (rpnt == link) 747 goto fail; 748 brelse(bh); 749 *rpnt = '\0'; 750 SetPageUptodate(page); 751 kunmap(page); 752 unlock_page(page); 753 return 0; 754 755 /* error exit from macro */ 756 out: 757 kfree(rs.buffer); 758 goto fail; 759 out_noread: 760 printk("unable to read i-node block"); 761 goto fail; 762 out_bad_span: 763 printk("symlink spans iso9660 blocks\n"); 764 fail: 765 brelse(bh); 766 error: 767 SetPageError(page); 768 kunmap(page); 769 unlock_page(page); 770 return -EIO; 771 } 772 773 const struct address_space_operations isofs_symlink_aops = { 774 .readpage = rock_ridge_symlink_readpage 775 }; 776