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		if (rr->len < 3)
213			goto out;	/* Something got screwed up here */
214		sig = isonum_721(rs.chr);
215		if (rock_check_overflow(&rs, sig))
216			goto eio;
217		rs.chr += rr->len;
218		rs.len -= rr->len;
219		if (rs.len < 0)
220			goto eio;	/* corrupted isofs */
221
222		switch (sig) {
223		case SIG('R', 'R'):
224			if ((rr->u.RR.flags[0] & RR_NM) == 0)
225				goto out;
226			break;
227		case SIG('S', 'P'):
228			if (check_sp(rr, inode))
229				goto out;
230			break;
231		case SIG('C', 'E'):
232			rs.cont_extent = isonum_733(rr->u.CE.extent);
233			rs.cont_offset = isonum_733(rr->u.CE.offset);
234			rs.cont_size = isonum_733(rr->u.CE.size);
235			break;
236		case SIG('N', 'M'):
237			if (truncate)
238				break;
239			if (rr->len < 5)
240				break;
241			/*
242			 * If the flags are 2 or 4, this indicates '.' or '..'.
243			 * We don't want to do anything with this, because it
244			 * screws up the code that calls us.  We don't really
245			 * care anyways, since we can just use the non-RR
246			 * name.
247			 */
248			if (rr->u.NM.flags & 6)
249				break;
250
251			if (rr->u.NM.flags & ~1) {
252				printk("Unsupported NM flag settings (%d)\n",
253					rr->u.NM.flags);
254				break;
255			}
256			if ((strlen(retname) + rr->len - 5) >= 254) {
257				truncate = 1;
258				break;
259			}
260			strncat(retname, rr->u.NM.name, rr->len - 5);
261			retnamlen += rr->len - 5;
262			break;
263		case SIG('R', 'E'):
264			kfree(rs.buffer);
265			return -1;
266		default:
267			break;
268		}
269	}
270	ret = rock_continue(&rs);
271	if (ret == 0)
272		goto repeat;
273	if (ret == 1)
274		return retnamlen; /* If 0, this file did not have a NM field */
275out:
276	kfree(rs.buffer);
277	return ret;
278eio:
279	ret = -EIO;
280	goto out;
281}
282
283static int
284parse_rock_ridge_inode_internal(struct iso_directory_record *de,
285				struct inode *inode, int regard_xa)
286{
287	int symlink_len = 0;
288	int cnt, sig;
289	struct inode *reloc;
290	struct rock_ridge *rr;
291	int rootflag;
292	struct rock_state rs;
293	int ret = 0;
294
295	if (!ISOFS_SB(inode->i_sb)->s_rock)
296		return 0;
297
298	init_rock_state(&rs, inode);
299	setup_rock_ridge(de, inode, &rs);
300	if (regard_xa) {
301		rs.chr += 14;
302		rs.len -= 14;
303		if (rs.len < 0)
304			rs.len = 0;
305	}
306
307repeat:
308	while (rs.len > 2) { /* There may be one byte for padding somewhere */
309		rr = (struct rock_ridge *)rs.chr;
310		if (rr->len < 3)
311			goto out;	/* Something got screwed up here */
312		sig = isonum_721(rs.chr);
313		if (rock_check_overflow(&rs, sig))
314			goto eio;
315		rs.chr += rr->len;
316		rs.len -= rr->len;
317		if (rs.len < 0)
318			goto eio;	/* corrupted isofs */
319
320		switch (sig) {
321#ifndef CONFIG_ZISOFS		    /* No flag for SF or ZF */
322		case SIG('R', 'R'):
323			if ((rr->u.RR.flags[0] &
324			     (RR_PX | RR_TF | RR_SL | RR_CL)) == 0)
325				goto out;
326			break;
327#endif
328		case SIG('S', 'P'):
329			if (check_sp(rr, inode))
330				goto out;
331			break;
332		case SIG('C', 'E'):
333			rs.cont_extent = isonum_733(rr->u.CE.extent);
334			rs.cont_offset = isonum_733(rr->u.CE.offset);
335			rs.cont_size = isonum_733(rr->u.CE.size);
336			break;
337		case SIG('E', 'R'):
338			ISOFS_SB(inode->i_sb)->s_rock = 1;
339			printk(KERN_DEBUG "ISO 9660 Extensions: ");
340			{
341				int p;
342				for (p = 0; p < rr->u.ER.len_id; p++)
343					printk("%c", rr->u.ER.data[p]);
344			}
345			printk("\n");
346			break;
347		case SIG('P', 'X'):
348			inode->i_mode = isonum_733(rr->u.PX.mode);
349			inode->i_nlink = isonum_733(rr->u.PX.n_links);
350			inode->i_uid = isonum_733(rr->u.PX.uid);
351			inode->i_gid = isonum_733(rr->u.PX.gid);
352			break;
353		case SIG('P', 'N'):
354			{
355				int high, low;
356				high = isonum_733(rr->u.PN.dev_high);
357				low = isonum_733(rr->u.PN.dev_low);
358				/*
359				 * The Rock Ridge standard specifies that if
360				 * sizeof(dev_t) <= 4, then the high field is
361				 * unused, and the device number is completely
362				 * stored in the low field.  Some writers may
363				 * ignore this subtlety,
364				 * and as a result we test to see if the entire
365				 * device number is
366				 * stored in the low field, and use that.
367				 */
368				if ((low & ~0xff) && high == 0) {
369					inode->i_rdev =
370					    MKDEV(low >> 8, low & 0xff);
371				} else {
372					inode->i_rdev =
373					    MKDEV(high, low);
374				}
375			}
376			break;
377		case SIG('T', 'F'):
378			/*
379			 * Some RRIP writers incorrectly place ctime in the
380			 * TF_CREATE field. Try to handle this correctly for
381			 * either case.
382			 */
383			/* Rock ridge never appears on a High Sierra disk */
384			cnt = 0;
385			if (rr->u.TF.flags & TF_CREATE) {
386				inode->i_ctime.tv_sec =
387				    iso_date(rr->u.TF.times[cnt++].time,
388					     0);
389				inode->i_ctime.tv_nsec = 0;
390			}
391			if (rr->u.TF.flags & TF_MODIFY) {
392				inode->i_mtime.tv_sec =
393				    iso_date(rr->u.TF.times[cnt++].time,
394					     0);
395				inode->i_mtime.tv_nsec = 0;
396			}
397			if (rr->u.TF.flags & TF_ACCESS) {
398				inode->i_atime.tv_sec =
399				    iso_date(rr->u.TF.times[cnt++].time,
400					     0);
401				inode->i_atime.tv_nsec = 0;
402			}
403			if (rr->u.TF.flags & TF_ATTRIBUTES) {
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			break;
410		case SIG('S', 'L'):
411			{
412				int slen;
413				struct SL_component *slp;
414				struct SL_component *oldslp;
415				slen = rr->len - 5;
416				slp = &rr->u.SL.link;
417				inode->i_size = symlink_len;
418				while (slen > 1) {
419					rootflag = 0;
420					switch (slp->flags & ~1) {
421					case 0:
422						inode->i_size +=
423						    slp->len;
424						break;
425					case 2:
426						inode->i_size += 1;
427						break;
428					case 4:
429						inode->i_size += 2;
430						break;
431					case 8:
432						rootflag = 1;
433						inode->i_size += 1;
434						break;
435					default:
436						printk("Symlink component flag "
437							"not implemented\n");
438					}
439					slen -= slp->len + 2;
440					oldslp = slp;
441					slp = (struct SL_component *)
442						(((char *)slp) + slp->len + 2);
443
444					if (slen < 2) {
445						if (((rr->u.SL.
446						      flags & 1) != 0)
447						    &&
448						    ((oldslp->
449						      flags & 1) == 0))
450							inode->i_size +=
451							    1;
452						break;
453					}
454
455					/*
456					 * If this component record isn't
457					 * continued, then append a '/'.
458					 */
459					if (!rootflag
460					    && (oldslp->flags & 1) == 0)
461						inode->i_size += 1;
462				}
463			}
464			symlink_len = inode->i_size;
465			break;
466		case SIG('R', 'E'):
467			printk(KERN_WARNING "Attempt to read inode for "
468					"relocated directory\n");
469			goto out;
470		case SIG('C', 'L'):
471			ISOFS_I(inode)->i_first_extent =
472			    isonum_733(rr->u.CL.location);
473			reloc =
474			    isofs_iget(inode->i_sb,
475				       ISOFS_I(inode)->i_first_extent,
476				       0);
477			if (!reloc)
478				goto out;
479			inode->i_mode = reloc->i_mode;
480			inode->i_nlink = reloc->i_nlink;
481			inode->i_uid = reloc->i_uid;
482			inode->i_gid = reloc->i_gid;
483			inode->i_rdev = reloc->i_rdev;
484			inode->i_size = reloc->i_size;
485			inode->i_blocks = reloc->i_blocks;
486			inode->i_atime = reloc->i_atime;
487			inode->i_ctime = reloc->i_ctime;
488			inode->i_mtime = reloc->i_mtime;
489			iput(reloc);
490			break;
491#ifdef CONFIG_ZISOFS
492		case SIG('Z', 'F'): {
493			int algo;
494
495			if (ISOFS_SB(inode->i_sb)->s_nocompress)
496				break;
497			algo = isonum_721(rr->u.ZF.algorithm);
498			if (algo == SIG('p', 'z')) {
499				int block_shift =
500					isonum_711(&rr->u.ZF.parms[1]);
501				if (block_shift < PAGE_CACHE_SHIFT
502						|| block_shift > 17) {
503					printk(KERN_WARNING "isofs: "
504						"Can't handle ZF block "
505						"size of 2^%d\n",
506						block_shift);
507				} else {
508					/*
509					 * Note: we don't change
510					 * i_blocks here
511					 */
512					ISOFS_I(inode)->i_file_format =
513						isofs_file_compressed;
514					/*
515					 * Parameters to compression
516					 * algorithm (header size,
517					 * block size)
518					 */
519					ISOFS_I(inode)->i_format_parm[0] =
520						isonum_711(&rr->u.ZF.parms[0]);
521					ISOFS_I(inode)->i_format_parm[1] =
522						isonum_711(&rr->u.ZF.parms[1]);
523					inode->i_size =
524					    isonum_733(rr->u.ZF.
525						       real_size);
526				}
527			} else {
528				printk(KERN_WARNING
529				       "isofs: Unknown ZF compression "
530						"algorithm: %c%c\n",
531				       rr->u.ZF.algorithm[0],
532				       rr->u.ZF.algorithm[1]);
533			}
534			break;
535		}
536#endif
537		default:
538			break;
539		}
540	}
541	ret = rock_continue(&rs);
542	if (ret == 0)
543		goto repeat;
544	if (ret == 1)
545		ret = 0;
546out:
547	kfree(rs.buffer);
548	return ret;
549eio:
550	ret = -EIO;
551	goto out;
552}
553
554static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit)
555{
556	int slen;
557	int rootflag;
558	struct SL_component *oldslp;
559	struct SL_component *slp;
560	slen = rr->len - 5;
561	slp = &rr->u.SL.link;
562	while (slen > 1) {
563		rootflag = 0;
564		switch (slp->flags & ~1) {
565		case 0:
566			if (slp->len > plimit - rpnt)
567				return NULL;
568			memcpy(rpnt, slp->text, slp->len);
569			rpnt += slp->len;
570			break;
571		case 2:
572			if (rpnt >= plimit)
573				return NULL;
574			*rpnt++ = '.';
575			break;
576		case 4:
577			if (2 > plimit - rpnt)
578				return NULL;
579			*rpnt++ = '.';
580			*rpnt++ = '.';
581			break;
582		case 8:
583			if (rpnt >= plimit)
584				return NULL;
585			rootflag = 1;
586			*rpnt++ = '/';
587			break;
588		default:
589			printk("Symlink component flag not implemented (%d)\n",
590			       slp->flags);
591		}
592		slen -= slp->len + 2;
593		oldslp = slp;
594		slp = (struct SL_component *)((char *)slp + slp->len + 2);
595
596		if (slen < 2) {
597			/*
598			 * If there is another SL record, and this component
599			 * record isn't continued, then add a slash.
600			 */
601			if ((!rootflag) && (rr->u.SL.flags & 1) &&
602			    !(oldslp->flags & 1)) {
603				if (rpnt >= plimit)
604					return NULL;
605				*rpnt++ = '/';
606			}
607			break;
608		}
609
610		/*
611		 * If this component record isn't continued, then append a '/'.
612		 */
613		if (!rootflag && !(oldslp->flags & 1)) {
614			if (rpnt >= plimit)
615				return NULL;
616			*rpnt++ = '/';
617		}
618	}
619	return rpnt;
620}
621
622int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode)
623{
624	int result = parse_rock_ridge_inode_internal(de, inode, 0);
625
626	/*
627	 * if rockridge flag was reset and we didn't look for attributes
628	 * behind eventual XA attributes, have a look there
629	 */
630	if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1)
631	    && (ISOFS_SB(inode->i_sb)->s_rock == 2)) {
632		result = parse_rock_ridge_inode_internal(de, inode, 14);
633	}
634	return result;
635}
636
637/*
638 * readpage() for symlinks: reads symlink contents into the page and either
639 * makes it uptodate and returns 0 or returns error (-EIO)
640 */
641static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
642{
643	struct inode *inode = page->mapping->host;
644	struct iso_inode_info *ei = ISOFS_I(inode);
645	char *link = kmap(page);
646	unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
647	struct buffer_head *bh;
648	char *rpnt = link;
649	unsigned char *pnt;
650	struct iso_directory_record *raw_de;
651	unsigned long block, offset;
652	int sig;
653	struct rock_ridge *rr;
654	struct rock_state rs;
655	int ret;
656
657	if (!ISOFS_SB(inode->i_sb)->s_rock)
658		goto error;
659
660	init_rock_state(&rs, inode);
661	block = ei->i_iget5_block;
662	lock_kernel();
663	bh = sb_bread(inode->i_sb, block);
664	if (!bh)
665		goto out_noread;
666
667	offset = ei->i_iget5_offset;
668	pnt = (unsigned char *)bh->b_data + offset;
669
670	raw_de = (struct iso_directory_record *)pnt;
671
672	/*
673	 * If we go past the end of the buffer, there is some sort of error.
674	 */
675	if (offset + *pnt > bufsize)
676		goto out_bad_span;
677
678	/*
679	 * Now test for possible Rock Ridge extensions which will override
680	 * some of these numbers in the inode structure.
681	 */
682
683	setup_rock_ridge(raw_de, inode, &rs);
684
685repeat:
686	while (rs.len > 2) { /* There may be one byte for padding somewhere */
687		rr = (struct rock_ridge *)rs.chr;
688		if (rr->len < 3)
689			goto out;	/* Something got screwed up here */
690		sig = isonum_721(rs.chr);
691		if (rock_check_overflow(&rs, sig))
692			goto out;
693		rs.chr += rr->len;
694		rs.len -= rr->len;
695		if (rs.len < 0)
696			goto out;	/* corrupted isofs */
697
698		switch (sig) {
699		case SIG('R', 'R'):
700			if ((rr->u.RR.flags[0] & RR_SL) == 0)
701				goto out;
702			break;
703		case SIG('S', 'P'):
704			if (check_sp(rr, inode))
705				goto out;
706			break;
707		case SIG('S', 'L'):
708			rpnt = get_symlink_chunk(rpnt, rr,
709						 link + (PAGE_SIZE - 1));
710			if (rpnt == NULL)
711				goto out;
712			break;
713		case SIG('C', 'E'):
714			/* This tells is if there is a continuation record */
715			rs.cont_extent = isonum_733(rr->u.CE.extent);
716			rs.cont_offset = isonum_733(rr->u.CE.offset);
717			rs.cont_size = isonum_733(rr->u.CE.size);
718		default:
719			break;
720		}
721	}
722	ret = rock_continue(&rs);
723	if (ret == 0)
724		goto repeat;
725	if (ret < 0)
726		goto fail;
727
728	if (rpnt == link)
729		goto fail;
730	brelse(bh);
731	*rpnt = '\0';
732	unlock_kernel();
733	SetPageUptodate(page);
734	kunmap(page);
735	unlock_page(page);
736	return 0;
737
738	/* error exit from macro */
739out:
740	kfree(rs.buffer);
741	goto fail;
742out_noread:
743	printk("unable to read i-node block");
744	goto fail;
745out_bad_span:
746	printk("symlink spans iso9660 blocks\n");
747fail:
748	brelse(bh);
749	unlock_kernel();
750error:
751	SetPageError(page);
752	kunmap(page);
753	unlock_page(page);
754	return -EIO;
755}
756
757const struct address_space_operations isofs_symlink_aops = {
758	.readpage = rock_ridge_symlink_readpage
759};
760