0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/slab.h>
0011 #include <linux/pagemap.h>
0012
0013 #include "isofs.h"
0014 #include "rock.h"
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #define SIG(A,B) ((A) | ((B) << 8))
0026
0027 struct rock_state {
0028 void *buffer;
0029 unsigned char *chr;
0030 int len;
0031 int cont_size;
0032 int cont_extent;
0033 int cont_offset;
0034 int cont_loops;
0035 struct inode *inode;
0036 };
0037
0038
0039
0040
0041
0042
0043 static int check_sp(struct rock_ridge *rr, struct inode *inode)
0044 {
0045 if (rr->u.SP.magic[0] != 0xbe)
0046 return -1;
0047 if (rr->u.SP.magic[1] != 0xef)
0048 return -1;
0049 ISOFS_SB(inode->i_sb)->s_rock_offset = rr->u.SP.skip;
0050 return 0;
0051 }
0052
0053 static void setup_rock_ridge(struct iso_directory_record *de,
0054 struct inode *inode, struct rock_state *rs)
0055 {
0056 rs->len = sizeof(struct iso_directory_record) + de->name_len[0];
0057 if (rs->len & 1)
0058 (rs->len)++;
0059 rs->chr = (unsigned char *)de + rs->len;
0060 rs->len = *((unsigned char *)de) - rs->len;
0061 if (rs->len < 0)
0062 rs->len = 0;
0063
0064 if (ISOFS_SB(inode->i_sb)->s_rock_offset != -1) {
0065 rs->len -= ISOFS_SB(inode->i_sb)->s_rock_offset;
0066 rs->chr += ISOFS_SB(inode->i_sb)->s_rock_offset;
0067 if (rs->len < 0)
0068 rs->len = 0;
0069 }
0070 }
0071
0072 static void init_rock_state(struct rock_state *rs, struct inode *inode)
0073 {
0074 memset(rs, 0, sizeof(*rs));
0075 rs->inode = inode;
0076 }
0077
0078
0079 #define RR_MAX_CE_ENTRIES 32
0080
0081
0082
0083
0084
0085 static int rock_continue(struct rock_state *rs)
0086 {
0087 int ret = 1;
0088 int blocksize = 1 << rs->inode->i_blkbits;
0089 const int min_de_size = offsetof(struct rock_ridge, u);
0090
0091 kfree(rs->buffer);
0092 rs->buffer = NULL;
0093
0094 if ((unsigned)rs->cont_offset > blocksize - min_de_size ||
0095 (unsigned)rs->cont_size > blocksize ||
0096 (unsigned)(rs->cont_offset + rs->cont_size) > blocksize) {
0097 printk(KERN_NOTICE "rock: corrupted directory entry. "
0098 "extent=%d, offset=%d, size=%d\n",
0099 rs->cont_extent, rs->cont_offset, rs->cont_size);
0100 ret = -EIO;
0101 goto out;
0102 }
0103
0104 if (rs->cont_extent) {
0105 struct buffer_head *bh;
0106
0107 rs->buffer = kmalloc(rs->cont_size, GFP_KERNEL);
0108 if (!rs->buffer) {
0109 ret = -ENOMEM;
0110 goto out;
0111 }
0112 ret = -EIO;
0113 if (++rs->cont_loops >= RR_MAX_CE_ENTRIES)
0114 goto out;
0115 bh = sb_bread(rs->inode->i_sb, rs->cont_extent);
0116 if (bh) {
0117 memcpy(rs->buffer, bh->b_data + rs->cont_offset,
0118 rs->cont_size);
0119 put_bh(bh);
0120 rs->chr = rs->buffer;
0121 rs->len = rs->cont_size;
0122 rs->cont_extent = 0;
0123 rs->cont_size = 0;
0124 rs->cont_offset = 0;
0125 return 0;
0126 }
0127 printk("Unable to read rock-ridge attributes\n");
0128 }
0129 out:
0130 kfree(rs->buffer);
0131 rs->buffer = NULL;
0132 return ret;
0133 }
0134
0135
0136
0137
0138
0139 static int rock_check_overflow(struct rock_state *rs, int sig)
0140 {
0141 int len;
0142
0143 switch (sig) {
0144 case SIG('S', 'P'):
0145 len = sizeof(struct SU_SP_s);
0146 break;
0147 case SIG('C', 'E'):
0148 len = sizeof(struct SU_CE_s);
0149 break;
0150 case SIG('E', 'R'):
0151 len = sizeof(struct SU_ER_s);
0152 break;
0153 case SIG('R', 'R'):
0154 len = sizeof(struct RR_RR_s);
0155 break;
0156 case SIG('P', 'X'):
0157 len = sizeof(struct RR_PX_s);
0158 break;
0159 case SIG('P', 'N'):
0160 len = sizeof(struct RR_PN_s);
0161 break;
0162 case SIG('S', 'L'):
0163 len = sizeof(struct RR_SL_s);
0164 break;
0165 case SIG('N', 'M'):
0166 len = sizeof(struct RR_NM_s);
0167 break;
0168 case SIG('C', 'L'):
0169 len = sizeof(struct RR_CL_s);
0170 break;
0171 case SIG('P', 'L'):
0172 len = sizeof(struct RR_PL_s);
0173 break;
0174 case SIG('T', 'F'):
0175 len = sizeof(struct RR_TF_s);
0176 break;
0177 case SIG('Z', 'F'):
0178 len = sizeof(struct RR_ZF_s);
0179 break;
0180 default:
0181 len = 0;
0182 break;
0183 }
0184 len += offsetof(struct rock_ridge, u);
0185 if (len > rs->len) {
0186 printk(KERN_NOTICE "rock: directory entry would overflow "
0187 "storage\n");
0188 printk(KERN_NOTICE "rock: sig=0x%02x, size=%d, remaining=%d\n",
0189 sig, len, rs->len);
0190 return -EIO;
0191 }
0192 return 0;
0193 }
0194
0195
0196
0197
0198 int get_rock_ridge_filename(struct iso_directory_record *de,
0199 char *retname, struct inode *inode)
0200 {
0201 struct rock_state rs;
0202 struct rock_ridge *rr;
0203 int sig;
0204 int retnamlen = 0;
0205 int truncate = 0;
0206 int ret = 0;
0207 char *p;
0208 int len;
0209
0210 if (!ISOFS_SB(inode->i_sb)->s_rock)
0211 return 0;
0212 *retname = 0;
0213
0214 init_rock_state(&rs, inode);
0215 setup_rock_ridge(de, inode, &rs);
0216 repeat:
0217
0218 while (rs.len > 2) {
0219 rr = (struct rock_ridge *)rs.chr;
0220
0221
0222
0223
0224
0225 if (rr->len < 3)
0226 goto out;
0227 sig = isonum_721(rs.chr);
0228 if (rock_check_overflow(&rs, sig))
0229 goto eio;
0230 rs.chr += rr->len;
0231 rs.len -= rr->len;
0232
0233
0234
0235
0236 if (rs.len < 0)
0237 goto out;
0238
0239 switch (sig) {
0240 case SIG('R', 'R'):
0241 if ((rr->u.RR.flags[0] & RR_NM) == 0)
0242 goto out;
0243 break;
0244 case SIG('S', 'P'):
0245 if (check_sp(rr, inode))
0246 goto out;
0247 break;
0248 case SIG('C', 'E'):
0249 rs.cont_extent = isonum_733(rr->u.CE.extent);
0250 rs.cont_offset = isonum_733(rr->u.CE.offset);
0251 rs.cont_size = isonum_733(rr->u.CE.size);
0252 break;
0253 case SIG('N', 'M'):
0254 if (truncate)
0255 break;
0256 if (rr->len < 5)
0257 break;
0258
0259
0260
0261
0262
0263
0264
0265 if (rr->u.NM.flags & 6)
0266 break;
0267
0268 if (rr->u.NM.flags & ~1) {
0269 printk("Unsupported NM flag settings (%d)\n",
0270 rr->u.NM.flags);
0271 break;
0272 }
0273 len = rr->len - 5;
0274 if (retnamlen + len >= 254) {
0275 truncate = 1;
0276 break;
0277 }
0278 p = memchr(rr->u.NM.name, '\0', len);
0279 if (unlikely(p))
0280 len = p - rr->u.NM.name;
0281 memcpy(retname + retnamlen, rr->u.NM.name, len);
0282 retnamlen += len;
0283 retname[retnamlen] = '\0';
0284 break;
0285 case SIG('R', 'E'):
0286 kfree(rs.buffer);
0287 return -1;
0288 default:
0289 break;
0290 }
0291 }
0292 ret = rock_continue(&rs);
0293 if (ret == 0)
0294 goto repeat;
0295 if (ret == 1)
0296 return retnamlen;
0297 out:
0298 kfree(rs.buffer);
0299 return ret;
0300 eio:
0301 ret = -EIO;
0302 goto out;
0303 }
0304
0305 #define RR_REGARD_XA 1
0306 #define RR_RELOC_DE 2
0307
0308 static int
0309 parse_rock_ridge_inode_internal(struct iso_directory_record *de,
0310 struct inode *inode, int flags)
0311 {
0312 int symlink_len = 0;
0313 int cnt, sig;
0314 unsigned int reloc_block;
0315 struct inode *reloc;
0316 struct rock_ridge *rr;
0317 int rootflag;
0318 struct rock_state rs;
0319 int ret = 0;
0320
0321 if (!ISOFS_SB(inode->i_sb)->s_rock)
0322 return 0;
0323
0324 init_rock_state(&rs, inode);
0325 setup_rock_ridge(de, inode, &rs);
0326 if (flags & RR_REGARD_XA) {
0327 rs.chr += 14;
0328 rs.len -= 14;
0329 if (rs.len < 0)
0330 rs.len = 0;
0331 }
0332
0333 repeat:
0334 while (rs.len > 2) {
0335 rr = (struct rock_ridge *)rs.chr;
0336
0337
0338
0339
0340
0341 if (rr->len < 3)
0342 goto out;
0343 sig = isonum_721(rs.chr);
0344 if (rock_check_overflow(&rs, sig))
0345 goto eio;
0346 rs.chr += rr->len;
0347 rs.len -= rr->len;
0348
0349
0350
0351
0352 if (rs.len < 0)
0353 goto out;
0354
0355 switch (sig) {
0356 #ifndef CONFIG_ZISOFS
0357 case SIG('R', 'R'):
0358 if ((rr->u.RR.flags[0] &
0359 (RR_PX | RR_TF | RR_SL | RR_CL)) == 0)
0360 goto out;
0361 break;
0362 #endif
0363 case SIG('S', 'P'):
0364 if (check_sp(rr, inode))
0365 goto out;
0366 break;
0367 case SIG('C', 'E'):
0368 rs.cont_extent = isonum_733(rr->u.CE.extent);
0369 rs.cont_offset = isonum_733(rr->u.CE.offset);
0370 rs.cont_size = isonum_733(rr->u.CE.size);
0371 break;
0372 case SIG('E', 'R'):
0373
0374 if (rr->u.ER.len_id + offsetof(struct rock_ridge, u.ER.data) > rr->len)
0375 goto out;
0376 ISOFS_SB(inode->i_sb)->s_rock = 1;
0377 printk(KERN_DEBUG "ISO 9660 Extensions: ");
0378 {
0379 int p;
0380 for (p = 0; p < rr->u.ER.len_id; p++)
0381 printk(KERN_CONT "%c", rr->u.ER.data[p]);
0382 }
0383 printk(KERN_CONT "\n");
0384 break;
0385 case SIG('P', 'X'):
0386 inode->i_mode = isonum_733(rr->u.PX.mode);
0387 set_nlink(inode, isonum_733(rr->u.PX.n_links));
0388 i_uid_write(inode, isonum_733(rr->u.PX.uid));
0389 i_gid_write(inode, isonum_733(rr->u.PX.gid));
0390 break;
0391 case SIG('P', 'N'):
0392 {
0393 int high, low;
0394 high = isonum_733(rr->u.PN.dev_high);
0395 low = isonum_733(rr->u.PN.dev_low);
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406 if ((low & ~0xff) && high == 0) {
0407 inode->i_rdev =
0408 MKDEV(low >> 8, low & 0xff);
0409 } else {
0410 inode->i_rdev =
0411 MKDEV(high, low);
0412 }
0413 }
0414 break;
0415 case SIG('T', 'F'):
0416
0417
0418
0419
0420
0421
0422 cnt = 0;
0423 if (rr->u.TF.flags & TF_CREATE) {
0424 inode->i_ctime.tv_sec =
0425 iso_date(rr->u.TF.times[cnt++].time,
0426 0);
0427 inode->i_ctime.tv_nsec = 0;
0428 }
0429 if (rr->u.TF.flags & TF_MODIFY) {
0430 inode->i_mtime.tv_sec =
0431 iso_date(rr->u.TF.times[cnt++].time,
0432 0);
0433 inode->i_mtime.tv_nsec = 0;
0434 }
0435 if (rr->u.TF.flags & TF_ACCESS) {
0436 inode->i_atime.tv_sec =
0437 iso_date(rr->u.TF.times[cnt++].time,
0438 0);
0439 inode->i_atime.tv_nsec = 0;
0440 }
0441 if (rr->u.TF.flags & TF_ATTRIBUTES) {
0442 inode->i_ctime.tv_sec =
0443 iso_date(rr->u.TF.times[cnt++].time,
0444 0);
0445 inode->i_ctime.tv_nsec = 0;
0446 }
0447 break;
0448 case SIG('S', 'L'):
0449 {
0450 int slen;
0451 struct SL_component *slp;
0452 struct SL_component *oldslp;
0453 slen = rr->len - 5;
0454 slp = &rr->u.SL.link;
0455 inode->i_size = symlink_len;
0456 while (slen > 1) {
0457 rootflag = 0;
0458 switch (slp->flags & ~1) {
0459 case 0:
0460 inode->i_size +=
0461 slp->len;
0462 break;
0463 case 2:
0464 inode->i_size += 1;
0465 break;
0466 case 4:
0467 inode->i_size += 2;
0468 break;
0469 case 8:
0470 rootflag = 1;
0471 inode->i_size += 1;
0472 break;
0473 default:
0474 printk("Symlink component flag "
0475 "not implemented\n");
0476 }
0477 slen -= slp->len + 2;
0478 oldslp = slp;
0479 slp = (struct SL_component *)
0480 (((char *)slp) + slp->len + 2);
0481
0482 if (slen < 2) {
0483 if (((rr->u.SL.
0484 flags & 1) != 0)
0485 &&
0486 ((oldslp->
0487 flags & 1) == 0))
0488 inode->i_size +=
0489 1;
0490 break;
0491 }
0492
0493
0494
0495
0496
0497 if (!rootflag
0498 && (oldslp->flags & 1) == 0)
0499 inode->i_size += 1;
0500 }
0501 }
0502 symlink_len = inode->i_size;
0503 break;
0504 case SIG('R', 'E'):
0505 printk(KERN_WARNING "Attempt to read inode for "
0506 "relocated directory\n");
0507 goto out;
0508 case SIG('C', 'L'):
0509 if (flags & RR_RELOC_DE) {
0510 printk(KERN_ERR
0511 "ISOFS: Recursive directory relocation "
0512 "is not supported\n");
0513 goto eio;
0514 }
0515 reloc_block = isonum_733(rr->u.CL.location);
0516 if (reloc_block == ISOFS_I(inode)->i_iget5_block &&
0517 ISOFS_I(inode)->i_iget5_offset == 0) {
0518 printk(KERN_ERR
0519 "ISOFS: Directory relocation points to "
0520 "itself\n");
0521 goto eio;
0522 }
0523 ISOFS_I(inode)->i_first_extent = reloc_block;
0524 reloc = isofs_iget_reloc(inode->i_sb, reloc_block, 0);
0525 if (IS_ERR(reloc)) {
0526 ret = PTR_ERR(reloc);
0527 goto out;
0528 }
0529 inode->i_mode = reloc->i_mode;
0530 set_nlink(inode, reloc->i_nlink);
0531 inode->i_uid = reloc->i_uid;
0532 inode->i_gid = reloc->i_gid;
0533 inode->i_rdev = reloc->i_rdev;
0534 inode->i_size = reloc->i_size;
0535 inode->i_blocks = reloc->i_blocks;
0536 inode->i_atime = reloc->i_atime;
0537 inode->i_ctime = reloc->i_ctime;
0538 inode->i_mtime = reloc->i_mtime;
0539 iput(reloc);
0540 break;
0541 #ifdef CONFIG_ZISOFS
0542 case SIG('Z', 'F'): {
0543 int algo;
0544
0545 if (ISOFS_SB(inode->i_sb)->s_nocompress)
0546 break;
0547 algo = isonum_721(rr->u.ZF.algorithm);
0548 if (algo == SIG('p', 'z')) {
0549 int block_shift =
0550 isonum_711(&rr->u.ZF.parms[1]);
0551 if (block_shift > 17) {
0552 printk(KERN_WARNING "isofs: "
0553 "Can't handle ZF block "
0554 "size of 2^%d\n",
0555 block_shift);
0556 } else {
0557
0558
0559
0560
0561 ISOFS_I(inode)->i_file_format =
0562 isofs_file_compressed;
0563
0564
0565
0566
0567
0568 ISOFS_I(inode)->i_format_parm[0] =
0569 isonum_711(&rr->u.ZF.parms[0]);
0570 ISOFS_I(inode)->i_format_parm[1] =
0571 isonum_711(&rr->u.ZF.parms[1]);
0572 inode->i_size =
0573 isonum_733(rr->u.ZF.
0574 real_size);
0575 }
0576 } else {
0577 printk(KERN_WARNING
0578 "isofs: Unknown ZF compression "
0579 "algorithm: %c%c\n",
0580 rr->u.ZF.algorithm[0],
0581 rr->u.ZF.algorithm[1]);
0582 }
0583 break;
0584 }
0585 #endif
0586 default:
0587 break;
0588 }
0589 }
0590 ret = rock_continue(&rs);
0591 if (ret == 0)
0592 goto repeat;
0593 if (ret == 1)
0594 ret = 0;
0595 out:
0596 kfree(rs.buffer);
0597 return ret;
0598 eio:
0599 ret = -EIO;
0600 goto out;
0601 }
0602
0603 static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit)
0604 {
0605 int slen;
0606 int rootflag;
0607 struct SL_component *oldslp;
0608 struct SL_component *slp;
0609 slen = rr->len - 5;
0610 slp = &rr->u.SL.link;
0611 while (slen > 1) {
0612 rootflag = 0;
0613 switch (slp->flags & ~1) {
0614 case 0:
0615 if (slp->len > plimit - rpnt)
0616 return NULL;
0617 memcpy(rpnt, slp->text, slp->len);
0618 rpnt += slp->len;
0619 break;
0620 case 2:
0621 if (rpnt >= plimit)
0622 return NULL;
0623 *rpnt++ = '.';
0624 break;
0625 case 4:
0626 if (2 > plimit - rpnt)
0627 return NULL;
0628 *rpnt++ = '.';
0629 *rpnt++ = '.';
0630 break;
0631 case 8:
0632 if (rpnt >= plimit)
0633 return NULL;
0634 rootflag = 1;
0635 *rpnt++ = '/';
0636 break;
0637 default:
0638 printk("Symlink component flag not implemented (%d)\n",
0639 slp->flags);
0640 }
0641 slen -= slp->len + 2;
0642 oldslp = slp;
0643 slp = (struct SL_component *)((char *)slp + slp->len + 2);
0644
0645 if (slen < 2) {
0646
0647
0648
0649
0650 if ((!rootflag) && (rr->u.SL.flags & 1) &&
0651 !(oldslp->flags & 1)) {
0652 if (rpnt >= plimit)
0653 return NULL;
0654 *rpnt++ = '/';
0655 }
0656 break;
0657 }
0658
0659
0660
0661
0662 if (!rootflag && !(oldslp->flags & 1)) {
0663 if (rpnt >= plimit)
0664 return NULL;
0665 *rpnt++ = '/';
0666 }
0667 }
0668 return rpnt;
0669 }
0670
0671 int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode,
0672 int relocated)
0673 {
0674 int flags = relocated ? RR_RELOC_DE : 0;
0675 int result = parse_rock_ridge_inode_internal(de, inode, flags);
0676
0677
0678
0679
0680
0681 if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1)
0682 && (ISOFS_SB(inode->i_sb)->s_rock == 2)) {
0683 result = parse_rock_ridge_inode_internal(de, inode,
0684 flags | RR_REGARD_XA);
0685 }
0686 return result;
0687 }
0688
0689
0690
0691
0692
0693 static int rock_ridge_symlink_read_folio(struct file *file, struct folio *folio)
0694 {
0695 struct page *page = &folio->page;
0696 struct inode *inode = page->mapping->host;
0697 struct iso_inode_info *ei = ISOFS_I(inode);
0698 struct isofs_sb_info *sbi = ISOFS_SB(inode->i_sb);
0699 char *link = page_address(page);
0700 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
0701 struct buffer_head *bh;
0702 char *rpnt = link;
0703 unsigned char *pnt;
0704 struct iso_directory_record *raw_de;
0705 unsigned long block, offset;
0706 int sig;
0707 struct rock_ridge *rr;
0708 struct rock_state rs;
0709 int ret;
0710
0711 if (!sbi->s_rock)
0712 goto error;
0713
0714 init_rock_state(&rs, inode);
0715 block = ei->i_iget5_block;
0716 bh = sb_bread(inode->i_sb, block);
0717 if (!bh)
0718 goto out_noread;
0719
0720 offset = ei->i_iget5_offset;
0721 pnt = (unsigned char *)bh->b_data + offset;
0722
0723 raw_de = (struct iso_directory_record *)pnt;
0724
0725
0726
0727
0728 if (offset + *pnt > bufsize)
0729 goto out_bad_span;
0730
0731
0732
0733
0734
0735
0736 setup_rock_ridge(raw_de, inode, &rs);
0737
0738 repeat:
0739 while (rs.len > 2) {
0740 rr = (struct rock_ridge *)rs.chr;
0741 if (rr->len < 3)
0742 goto out;
0743 sig = isonum_721(rs.chr);
0744 if (rock_check_overflow(&rs, sig))
0745 goto out;
0746 rs.chr += rr->len;
0747 rs.len -= rr->len;
0748 if (rs.len < 0)
0749 goto out;
0750
0751 switch (sig) {
0752 case SIG('R', 'R'):
0753 if ((rr->u.RR.flags[0] & RR_SL) == 0)
0754 goto out;
0755 break;
0756 case SIG('S', 'P'):
0757 if (check_sp(rr, inode))
0758 goto out;
0759 break;
0760 case SIG('S', 'L'):
0761 rpnt = get_symlink_chunk(rpnt, rr,
0762 link + (PAGE_SIZE - 1));
0763 if (rpnt == NULL)
0764 goto out;
0765 break;
0766 case SIG('C', 'E'):
0767
0768 rs.cont_extent = isonum_733(rr->u.CE.extent);
0769 rs.cont_offset = isonum_733(rr->u.CE.offset);
0770 rs.cont_size = isonum_733(rr->u.CE.size);
0771 break;
0772 default:
0773 break;
0774 }
0775 }
0776 ret = rock_continue(&rs);
0777 if (ret == 0)
0778 goto repeat;
0779 if (ret < 0)
0780 goto fail;
0781
0782 if (rpnt == link)
0783 goto fail;
0784 brelse(bh);
0785 *rpnt = '\0';
0786 SetPageUptodate(page);
0787 unlock_page(page);
0788 return 0;
0789
0790
0791 out:
0792 kfree(rs.buffer);
0793 goto fail;
0794 out_noread:
0795 printk("unable to read i-node block");
0796 goto fail;
0797 out_bad_span:
0798 printk("symlink spans iso9660 blocks\n");
0799 fail:
0800 brelse(bh);
0801 error:
0802 SetPageError(page);
0803 unlock_page(page);
0804 return -EIO;
0805 }
0806
0807 const struct address_space_operations isofs_symlink_aops = {
0808 .read_folio = rock_ridge_symlink_read_folio
0809 };