Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rock.c
Go to the documentation of this file.
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;
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  */
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 =
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 {
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 
774  .readpage = rock_ridge_symlink_readpage
775 };