xref: /openbmc/linux/fs/squashfs/super.c (revision f0a86878)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Squashfs - a compressed read only filesystem for Linux
4  *
5  * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
6  * Phillip Lougher <phillip@squashfs.org.uk>
7  *
8  * super.c
9  */
10 
11 /*
12  * This file implements code to read the superblock, read and initialise
13  * in-memory structures at mount time, and all the VFS glue code to register
14  * the filesystem.
15  */
16 
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18 
19 #include <linux/blkdev.h>
20 #include <linux/fs.h>
21 #include <linux/fs_context.h>
22 #include <linux/fs_parser.h>
23 #include <linux/vfs.h>
24 #include <linux/slab.h>
25 #include <linux/mutex.h>
26 #include <linux/seq_file.h>
27 #include <linux/pagemap.h>
28 #include <linux/init.h>
29 #include <linux/module.h>
30 #include <linux/magic.h>
31 #include <linux/xattr.h>
32 
33 #include "squashfs_fs.h"
34 #include "squashfs_fs_sb.h"
35 #include "squashfs_fs_i.h"
36 #include "squashfs.h"
37 #include "decompressor.h"
38 #include "xattr.h"
39 
40 static struct file_system_type squashfs_fs_type;
41 static const struct super_operations squashfs_super_ops;
42 
43 enum Opt_errors {
44 	Opt_errors_continue,
45 	Opt_errors_panic,
46 };
47 
48 enum squashfs_param {
49 	Opt_errors,
50 };
51 
52 struct squashfs_mount_opts {
53 	enum Opt_errors errors;
54 };
55 
56 static const struct constant_table squashfs_param_errors[] = {
57 	{"continue",   Opt_errors_continue },
58 	{"panic",      Opt_errors_panic },
59 	{}
60 };
61 
62 static const struct fs_parameter_spec squashfs_fs_parameters[] = {
63 	fsparam_enum("errors", Opt_errors, squashfs_param_errors),
64 	{}
65 };
66 
67 static int squashfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
68 {
69 	struct squashfs_mount_opts *opts = fc->fs_private;
70 	struct fs_parse_result result;
71 	int opt;
72 
73 	opt = fs_parse(fc, squashfs_fs_parameters, param, &result);
74 	if (opt < 0)
75 		return opt;
76 
77 	switch (opt) {
78 	case Opt_errors:
79 		opts->errors = result.uint_32;
80 		break;
81 	default:
82 		return -EINVAL;
83 	}
84 
85 	return 0;
86 }
87 
88 static const struct squashfs_decompressor *supported_squashfs_filesystem(
89 	struct fs_context *fc,
90 	short major, short minor, short id)
91 {
92 	const struct squashfs_decompressor *decompressor;
93 
94 	if (major < SQUASHFS_MAJOR) {
95 		errorf(fc, "Major/Minor mismatch, older Squashfs %d.%d "
96 		       "filesystems are unsupported", major, minor);
97 		return NULL;
98 	} else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) {
99 		errorf(fc, "Major/Minor mismatch, trying to mount newer "
100 		       "%d.%d filesystem", major, minor);
101 		errorf(fc, "Please update your kernel");
102 		return NULL;
103 	}
104 
105 	decompressor = squashfs_lookup_decompressor(id);
106 	if (!decompressor->supported) {
107 		errorf(fc, "Filesystem uses \"%s\" compression. This is not supported",
108 		       decompressor->name);
109 		return NULL;
110 	}
111 
112 	return decompressor;
113 }
114 
115 
116 static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc)
117 {
118 	struct squashfs_mount_opts *opts = fc->fs_private;
119 	struct squashfs_sb_info *msblk;
120 	struct squashfs_super_block *sblk = NULL;
121 	struct inode *root;
122 	long long root_inode;
123 	unsigned short flags;
124 	unsigned int fragments;
125 	u64 lookup_table_start, xattr_id_table_start, next_table;
126 	int err;
127 
128 	TRACE("Entered squashfs_fill_superblock\n");
129 
130 	sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL);
131 	if (sb->s_fs_info == NULL) {
132 		ERROR("Failed to allocate squashfs_sb_info\n");
133 		return -ENOMEM;
134 	}
135 	msblk = sb->s_fs_info;
136 
137 	msblk->panic_on_errors = (opts->errors == Opt_errors_panic);
138 
139 	msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE);
140 	msblk->devblksize_log2 = ffz(~msblk->devblksize);
141 
142 	mutex_init(&msblk->meta_index_mutex);
143 
144 	/*
145 	 * msblk->bytes_used is checked in squashfs_read_table to ensure reads
146 	 * are not beyond filesystem end.  But as we're using
147 	 * squashfs_read_table here to read the superblock (including the value
148 	 * of bytes_used) we need to set it to an initial sensible dummy value
149 	 */
150 	msblk->bytes_used = sizeof(*sblk);
151 	sblk = squashfs_read_table(sb, SQUASHFS_START, sizeof(*sblk));
152 
153 	if (IS_ERR(sblk)) {
154 		errorf(fc, "unable to read squashfs_super_block");
155 		err = PTR_ERR(sblk);
156 		sblk = NULL;
157 		goto failed_mount;
158 	}
159 
160 	err = -EINVAL;
161 
162 	/* Check it is a SQUASHFS superblock */
163 	sb->s_magic = le32_to_cpu(sblk->s_magic);
164 	if (sb->s_magic != SQUASHFS_MAGIC) {
165 		if (!(fc->sb_flags & SB_SILENT))
166 			errorf(fc, "Can't find a SQUASHFS superblock on %pg",
167 			       sb->s_bdev);
168 		goto failed_mount;
169 	}
170 
171 	/* Check the MAJOR & MINOR versions and lookup compression type */
172 	msblk->decompressor = supported_squashfs_filesystem(
173 			fc,
174 			le16_to_cpu(sblk->s_major),
175 			le16_to_cpu(sblk->s_minor),
176 			le16_to_cpu(sblk->compression));
177 	if (msblk->decompressor == NULL)
178 		goto failed_mount;
179 
180 	/* Check the filesystem does not extend beyond the end of the
181 	   block device */
182 	msblk->bytes_used = le64_to_cpu(sblk->bytes_used);
183 	if (msblk->bytes_used < 0 ||
184 	    msblk->bytes_used > bdev_nr_bytes(sb->s_bdev))
185 		goto failed_mount;
186 
187 	/* Check block size for sanity */
188 	msblk->block_size = le32_to_cpu(sblk->block_size);
189 	if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE)
190 		goto insanity;
191 
192 	/*
193 	 * Check the system page size is not larger than the filesystem
194 	 * block size (by default 128K).  This is currently not supported.
195 	 */
196 	if (PAGE_SIZE > msblk->block_size) {
197 		errorf(fc, "Page size > filesystem block size (%d).  This is "
198 		       "currently not supported!", msblk->block_size);
199 		goto failed_mount;
200 	}
201 
202 	/* Check block log for sanity */
203 	msblk->block_log = le16_to_cpu(sblk->block_log);
204 	if (msblk->block_log > SQUASHFS_FILE_MAX_LOG)
205 		goto failed_mount;
206 
207 	/* Check that block_size and block_log match */
208 	if (msblk->block_size != (1 << msblk->block_log))
209 		goto insanity;
210 
211 	/* Check the root inode for sanity */
212 	root_inode = le64_to_cpu(sblk->root_inode);
213 	if (SQUASHFS_INODE_OFFSET(root_inode) > SQUASHFS_METADATA_SIZE)
214 		goto insanity;
215 
216 	msblk->inode_table = le64_to_cpu(sblk->inode_table_start);
217 	msblk->directory_table = le64_to_cpu(sblk->directory_table_start);
218 	msblk->inodes = le32_to_cpu(sblk->inodes);
219 	msblk->fragments = le32_to_cpu(sblk->fragments);
220 	msblk->ids = le16_to_cpu(sblk->no_ids);
221 	flags = le16_to_cpu(sblk->flags);
222 
223 	TRACE("Found valid superblock on %pg\n", sb->s_bdev);
224 	TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(flags)
225 				? "un" : "");
226 	TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(flags)
227 				? "un" : "");
228 	TRACE("Filesystem size %lld bytes\n", msblk->bytes_used);
229 	TRACE("Block size %d\n", msblk->block_size);
230 	TRACE("Number of inodes %d\n", msblk->inodes);
231 	TRACE("Number of fragments %d\n", msblk->fragments);
232 	TRACE("Number of ids %d\n", msblk->ids);
233 	TRACE("sblk->inode_table_start %llx\n", msblk->inode_table);
234 	TRACE("sblk->directory_table_start %llx\n", msblk->directory_table);
235 	TRACE("sblk->fragment_table_start %llx\n",
236 		(u64) le64_to_cpu(sblk->fragment_table_start));
237 	TRACE("sblk->id_table_start %llx\n",
238 		(u64) le64_to_cpu(sblk->id_table_start));
239 
240 	sb->s_maxbytes = MAX_LFS_FILESIZE;
241 	sb->s_time_min = 0;
242 	sb->s_time_max = U32_MAX;
243 	sb->s_flags |= SB_RDONLY;
244 	sb->s_op = &squashfs_super_ops;
245 
246 	err = -ENOMEM;
247 
248 	msblk->block_cache = squashfs_cache_init("metadata",
249 			SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE);
250 	if (msblk->block_cache == NULL)
251 		goto failed_mount;
252 
253 	/* Allocate read_page block */
254 	msblk->read_page = squashfs_cache_init("data",
255 		squashfs_max_decompressors(), msblk->block_size);
256 	if (msblk->read_page == NULL) {
257 		errorf(fc, "Failed to allocate read_page block");
258 		goto failed_mount;
259 	}
260 
261 	msblk->stream = squashfs_decompressor_setup(sb, flags);
262 	if (IS_ERR(msblk->stream)) {
263 		err = PTR_ERR(msblk->stream);
264 		msblk->stream = NULL;
265 		goto insanity;
266 	}
267 
268 	/* Handle xattrs */
269 	sb->s_xattr = squashfs_xattr_handlers;
270 	xattr_id_table_start = le64_to_cpu(sblk->xattr_id_table_start);
271 	if (xattr_id_table_start == SQUASHFS_INVALID_BLK) {
272 		next_table = msblk->bytes_used;
273 		goto allocate_id_index_table;
274 	}
275 
276 	/* Allocate and read xattr id lookup table */
277 	msblk->xattr_id_table = squashfs_read_xattr_id_table(sb,
278 		xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids);
279 	if (IS_ERR(msblk->xattr_id_table)) {
280 		errorf(fc, "unable to read xattr id index table");
281 		err = PTR_ERR(msblk->xattr_id_table);
282 		msblk->xattr_id_table = NULL;
283 		if (err != -ENOTSUPP)
284 			goto failed_mount;
285 	}
286 	next_table = msblk->xattr_table;
287 
288 allocate_id_index_table:
289 	/* Allocate and read id index table */
290 	msblk->id_table = squashfs_read_id_index_table(sb,
291 		le64_to_cpu(sblk->id_table_start), next_table, msblk->ids);
292 	if (IS_ERR(msblk->id_table)) {
293 		errorf(fc, "unable to read id index table");
294 		err = PTR_ERR(msblk->id_table);
295 		msblk->id_table = NULL;
296 		goto failed_mount;
297 	}
298 	next_table = le64_to_cpu(msblk->id_table[0]);
299 
300 	/* Handle inode lookup table */
301 	lookup_table_start = le64_to_cpu(sblk->lookup_table_start);
302 	if (lookup_table_start == SQUASHFS_INVALID_BLK)
303 		goto handle_fragments;
304 
305 	/* Allocate and read inode lookup table */
306 	msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
307 		lookup_table_start, next_table, msblk->inodes);
308 	if (IS_ERR(msblk->inode_lookup_table)) {
309 		errorf(fc, "unable to read inode lookup table");
310 		err = PTR_ERR(msblk->inode_lookup_table);
311 		msblk->inode_lookup_table = NULL;
312 		goto failed_mount;
313 	}
314 	next_table = le64_to_cpu(msblk->inode_lookup_table[0]);
315 
316 	sb->s_export_op = &squashfs_export_ops;
317 
318 handle_fragments:
319 	fragments = msblk->fragments;
320 	if (fragments == 0)
321 		goto check_directory_table;
322 
323 	msblk->fragment_cache = squashfs_cache_init("fragment",
324 		SQUASHFS_CACHED_FRAGMENTS, msblk->block_size);
325 	if (msblk->fragment_cache == NULL) {
326 		err = -ENOMEM;
327 		goto failed_mount;
328 	}
329 
330 	/* Allocate and read fragment index table */
331 	msblk->fragment_index = squashfs_read_fragment_index_table(sb,
332 		le64_to_cpu(sblk->fragment_table_start), next_table, fragments);
333 	if (IS_ERR(msblk->fragment_index)) {
334 		errorf(fc, "unable to read fragment index table");
335 		err = PTR_ERR(msblk->fragment_index);
336 		msblk->fragment_index = NULL;
337 		goto failed_mount;
338 	}
339 	next_table = le64_to_cpu(msblk->fragment_index[0]);
340 
341 check_directory_table:
342 	/* Sanity check directory_table */
343 	if (msblk->directory_table > next_table) {
344 		err = -EINVAL;
345 		goto insanity;
346 	}
347 
348 	/* Sanity check inode_table */
349 	if (msblk->inode_table >= msblk->directory_table) {
350 		err = -EINVAL;
351 		goto insanity;
352 	}
353 
354 	/* allocate root */
355 	root = new_inode(sb);
356 	if (!root) {
357 		err = -ENOMEM;
358 		goto failed_mount;
359 	}
360 
361 	err = squashfs_read_inode(root, root_inode);
362 	if (err) {
363 		make_bad_inode(root);
364 		iput(root);
365 		goto failed_mount;
366 	}
367 	insert_inode_hash(root);
368 
369 	sb->s_root = d_make_root(root);
370 	if (sb->s_root == NULL) {
371 		ERROR("Root inode create failed\n");
372 		err = -ENOMEM;
373 		goto failed_mount;
374 	}
375 
376 	TRACE("Leaving squashfs_fill_super\n");
377 	kfree(sblk);
378 	return 0;
379 
380 insanity:
381 	errorf(fc, "squashfs image failed sanity check");
382 failed_mount:
383 	squashfs_cache_delete(msblk->block_cache);
384 	squashfs_cache_delete(msblk->fragment_cache);
385 	squashfs_cache_delete(msblk->read_page);
386 	squashfs_decompressor_destroy(msblk);
387 	kfree(msblk->inode_lookup_table);
388 	kfree(msblk->fragment_index);
389 	kfree(msblk->id_table);
390 	kfree(msblk->xattr_id_table);
391 	kfree(sb->s_fs_info);
392 	sb->s_fs_info = NULL;
393 	kfree(sblk);
394 	return err;
395 }
396 
397 static int squashfs_get_tree(struct fs_context *fc)
398 {
399 	return get_tree_bdev(fc, squashfs_fill_super);
400 }
401 
402 static int squashfs_reconfigure(struct fs_context *fc)
403 {
404 	struct super_block *sb = fc->root->d_sb;
405 	struct squashfs_sb_info *msblk = sb->s_fs_info;
406 	struct squashfs_mount_opts *opts = fc->fs_private;
407 
408 	sync_filesystem(fc->root->d_sb);
409 	fc->sb_flags |= SB_RDONLY;
410 
411 	msblk->panic_on_errors = (opts->errors == Opt_errors_panic);
412 
413 	return 0;
414 }
415 
416 static void squashfs_free_fs_context(struct fs_context *fc)
417 {
418 	kfree(fc->fs_private);
419 }
420 
421 static const struct fs_context_operations squashfs_context_ops = {
422 	.get_tree	= squashfs_get_tree,
423 	.free		= squashfs_free_fs_context,
424 	.parse_param	= squashfs_parse_param,
425 	.reconfigure	= squashfs_reconfigure,
426 };
427 
428 static int squashfs_show_options(struct seq_file *s, struct dentry *root)
429 {
430 	struct super_block *sb = root->d_sb;
431 	struct squashfs_sb_info *msblk = sb->s_fs_info;
432 
433 	if (msblk->panic_on_errors)
434 		seq_puts(s, ",errors=panic");
435 	else
436 		seq_puts(s, ",errors=continue");
437 
438 	return 0;
439 }
440 
441 static int squashfs_init_fs_context(struct fs_context *fc)
442 {
443 	struct squashfs_mount_opts *opts;
444 
445 	opts = kzalloc(sizeof(*opts), GFP_KERNEL);
446 	if (!opts)
447 		return -ENOMEM;
448 
449 	fc->fs_private = opts;
450 	fc->ops = &squashfs_context_ops;
451 	return 0;
452 }
453 
454 static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
455 {
456 	struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info;
457 	u64 id = huge_encode_dev(dentry->d_sb->s_bdev->bd_dev);
458 
459 	TRACE("Entered squashfs_statfs\n");
460 
461 	buf->f_type = SQUASHFS_MAGIC;
462 	buf->f_bsize = msblk->block_size;
463 	buf->f_blocks = ((msblk->bytes_used - 1) >> msblk->block_log) + 1;
464 	buf->f_bfree = buf->f_bavail = 0;
465 	buf->f_files = msblk->inodes;
466 	buf->f_ffree = 0;
467 	buf->f_namelen = SQUASHFS_NAME_LEN;
468 	buf->f_fsid = u64_to_fsid(id);
469 
470 	return 0;
471 }
472 
473 
474 static void squashfs_put_super(struct super_block *sb)
475 {
476 	if (sb->s_fs_info) {
477 		struct squashfs_sb_info *sbi = sb->s_fs_info;
478 		squashfs_cache_delete(sbi->block_cache);
479 		squashfs_cache_delete(sbi->fragment_cache);
480 		squashfs_cache_delete(sbi->read_page);
481 		squashfs_decompressor_destroy(sbi);
482 		kfree(sbi->id_table);
483 		kfree(sbi->fragment_index);
484 		kfree(sbi->meta_index);
485 		kfree(sbi->inode_lookup_table);
486 		kfree(sbi->xattr_id_table);
487 		kfree(sb->s_fs_info);
488 		sb->s_fs_info = NULL;
489 	}
490 }
491 
492 static struct kmem_cache *squashfs_inode_cachep;
493 
494 
495 static void init_once(void *foo)
496 {
497 	struct squashfs_inode_info *ei = foo;
498 
499 	inode_init_once(&ei->vfs_inode);
500 }
501 
502 
503 static int __init init_inodecache(void)
504 {
505 	squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache",
506 		sizeof(struct squashfs_inode_info), 0,
507 		SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_ACCOUNT,
508 		init_once);
509 
510 	return squashfs_inode_cachep ? 0 : -ENOMEM;
511 }
512 
513 
514 static void destroy_inodecache(void)
515 {
516 	/*
517 	 * Make sure all delayed rcu free inodes are flushed before we
518 	 * destroy cache.
519 	 */
520 	rcu_barrier();
521 	kmem_cache_destroy(squashfs_inode_cachep);
522 }
523 
524 
525 static int __init init_squashfs_fs(void)
526 {
527 	int err = init_inodecache();
528 
529 	if (err)
530 		return err;
531 
532 	err = register_filesystem(&squashfs_fs_type);
533 	if (err) {
534 		destroy_inodecache();
535 		return err;
536 	}
537 
538 	pr_info("version 4.0 (2009/01/31) Phillip Lougher\n");
539 
540 	return 0;
541 }
542 
543 
544 static void __exit exit_squashfs_fs(void)
545 {
546 	unregister_filesystem(&squashfs_fs_type);
547 	destroy_inodecache();
548 }
549 
550 
551 static struct inode *squashfs_alloc_inode(struct super_block *sb)
552 {
553 	struct squashfs_inode_info *ei =
554 		alloc_inode_sb(sb, squashfs_inode_cachep, GFP_KERNEL);
555 
556 	return ei ? &ei->vfs_inode : NULL;
557 }
558 
559 
560 static void squashfs_free_inode(struct inode *inode)
561 {
562 	kmem_cache_free(squashfs_inode_cachep, squashfs_i(inode));
563 }
564 
565 static struct file_system_type squashfs_fs_type = {
566 	.owner = THIS_MODULE,
567 	.name = "squashfs",
568 	.init_fs_context = squashfs_init_fs_context,
569 	.parameters = squashfs_fs_parameters,
570 	.kill_sb = kill_block_super,
571 	.fs_flags = FS_REQUIRES_DEV
572 };
573 MODULE_ALIAS_FS("squashfs");
574 
575 static const struct super_operations squashfs_super_ops = {
576 	.alloc_inode = squashfs_alloc_inode,
577 	.free_inode = squashfs_free_inode,
578 	.statfs = squashfs_statfs,
579 	.put_super = squashfs_put_super,
580 	.show_options = squashfs_show_options,
581 };
582 
583 module_init(init_squashfs_fs);
584 module_exit(exit_squashfs_fs);
585 MODULE_DESCRIPTION("squashfs 4.0, a compressed read-only filesystem");
586 MODULE_AUTHOR("Phillip Lougher <phillip@squashfs.org.uk>");
587 MODULE_LICENSE("GPL");
588