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