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