cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

super.c (11660B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  linux/fs/adfs/super.c
      4 *
      5 *  Copyright (C) 1997-1999 Russell King
      6 */
      7#include <linux/module.h>
      8#include <linux/init.h>
      9#include <linux/parser.h>
     10#include <linux/mount.h>
     11#include <linux/seq_file.h>
     12#include <linux/slab.h>
     13#include <linux/statfs.h>
     14#include <linux/user_namespace.h>
     15#include <linux/blkdev.h>
     16#include "adfs.h"
     17#include "dir_f.h"
     18#include "dir_fplus.h"
     19
     20#define ADFS_SB_FLAGS SB_NOATIME
     21
     22#define ADFS_DEFAULT_OWNER_MASK S_IRWXU
     23#define ADFS_DEFAULT_OTHER_MASK (S_IRWXG | S_IRWXO)
     24
     25void __adfs_error(struct super_block *sb, const char *function, const char *fmt, ...)
     26{
     27	struct va_format vaf;
     28	va_list args;
     29
     30	va_start(args, fmt);
     31	vaf.fmt = fmt;
     32	vaf.va = &args;
     33
     34	printk(KERN_CRIT "ADFS-fs error (device %s)%s%s: %pV\n",
     35		sb->s_id, function ? ": " : "",
     36		function ? function : "", &vaf);
     37
     38	va_end(args);
     39}
     40
     41void adfs_msg(struct super_block *sb, const char *pfx, const char *fmt, ...)
     42{
     43	struct va_format vaf;
     44	va_list args;
     45
     46	va_start(args, fmt);
     47	vaf.fmt = fmt;
     48	vaf.va = &args;
     49	printk("%sADFS-fs (%s): %pV\n", pfx, sb->s_id, &vaf);
     50	va_end(args);
     51}
     52
     53static int adfs_checkdiscrecord(struct adfs_discrecord *dr)
     54{
     55	unsigned int max_idlen;
     56	int i;
     57
     58	/* sector size must be 256, 512 or 1024 bytes */
     59	if (dr->log2secsize != 8 &&
     60	    dr->log2secsize != 9 &&
     61	    dr->log2secsize != 10)
     62		return 1;
     63
     64	/* idlen must be at least log2secsize + 3 */
     65	if (dr->idlen < dr->log2secsize + 3)
     66		return 1;
     67
     68	/* we cannot have such a large disc that we
     69	 * are unable to represent sector offsets in
     70	 * 32 bits.  This works out at 2.0 TB.
     71	 */
     72	if (le32_to_cpu(dr->disc_size_high) >> dr->log2secsize)
     73		return 1;
     74
     75	/*
     76	 * Maximum idlen is limited to 16 bits for new directories by
     77	 * the three-byte storage of an indirect disc address.  For
     78	 * big directories, idlen must be no greater than 19 v2 [1.0]
     79	 */
     80	max_idlen = dr->format_version ? 19 : 16;
     81	if (dr->idlen > max_idlen)
     82		return 1;
     83
     84	/* reserved bytes should be zero */
     85	for (i = 0; i < sizeof(dr->unused52); i++)
     86		if (dr->unused52[i] != 0)
     87			return 1;
     88
     89	return 0;
     90}
     91
     92static void adfs_put_super(struct super_block *sb)
     93{
     94	struct adfs_sb_info *asb = ADFS_SB(sb);
     95
     96	adfs_free_map(sb);
     97	kfree_rcu(asb, rcu);
     98}
     99
    100static int adfs_show_options(struct seq_file *seq, struct dentry *root)
    101{
    102	struct adfs_sb_info *asb = ADFS_SB(root->d_sb);
    103
    104	if (!uid_eq(asb->s_uid, GLOBAL_ROOT_UID))
    105		seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, asb->s_uid));
    106	if (!gid_eq(asb->s_gid, GLOBAL_ROOT_GID))
    107		seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, asb->s_gid));
    108	if (asb->s_owner_mask != ADFS_DEFAULT_OWNER_MASK)
    109		seq_printf(seq, ",ownmask=%o", asb->s_owner_mask);
    110	if (asb->s_other_mask != ADFS_DEFAULT_OTHER_MASK)
    111		seq_printf(seq, ",othmask=%o", asb->s_other_mask);
    112	if (asb->s_ftsuffix != 0)
    113		seq_printf(seq, ",ftsuffix=%u", asb->s_ftsuffix);
    114
    115	return 0;
    116}
    117
    118enum {Opt_uid, Opt_gid, Opt_ownmask, Opt_othmask, Opt_ftsuffix, Opt_err};
    119
    120static const match_table_t tokens = {
    121	{Opt_uid, "uid=%u"},
    122	{Opt_gid, "gid=%u"},
    123	{Opt_ownmask, "ownmask=%o"},
    124	{Opt_othmask, "othmask=%o"},
    125	{Opt_ftsuffix, "ftsuffix=%u"},
    126	{Opt_err, NULL}
    127};
    128
    129static int parse_options(struct super_block *sb, struct adfs_sb_info *asb,
    130			 char *options)
    131{
    132	char *p;
    133	int option;
    134
    135	if (!options)
    136		return 0;
    137
    138	while ((p = strsep(&options, ",")) != NULL) {
    139		substring_t args[MAX_OPT_ARGS];
    140		int token;
    141		if (!*p)
    142			continue;
    143
    144		token = match_token(p, tokens, args);
    145		switch (token) {
    146		case Opt_uid:
    147			if (match_int(args, &option))
    148				return -EINVAL;
    149			asb->s_uid = make_kuid(current_user_ns(), option);
    150			if (!uid_valid(asb->s_uid))
    151				return -EINVAL;
    152			break;
    153		case Opt_gid:
    154			if (match_int(args, &option))
    155				return -EINVAL;
    156			asb->s_gid = make_kgid(current_user_ns(), option);
    157			if (!gid_valid(asb->s_gid))
    158				return -EINVAL;
    159			break;
    160		case Opt_ownmask:
    161			if (match_octal(args, &option))
    162				return -EINVAL;
    163			asb->s_owner_mask = option;
    164			break;
    165		case Opt_othmask:
    166			if (match_octal(args, &option))
    167				return -EINVAL;
    168			asb->s_other_mask = option;
    169			break;
    170		case Opt_ftsuffix:
    171			if (match_int(args, &option))
    172				return -EINVAL;
    173			asb->s_ftsuffix = option;
    174			break;
    175		default:
    176			adfs_msg(sb, KERN_ERR,
    177				 "unrecognised mount option \"%s\" or missing value",
    178				 p);
    179			return -EINVAL;
    180		}
    181	}
    182	return 0;
    183}
    184
    185static int adfs_remount(struct super_block *sb, int *flags, char *data)
    186{
    187	struct adfs_sb_info temp_asb;
    188	int ret;
    189
    190	sync_filesystem(sb);
    191	*flags |= ADFS_SB_FLAGS;
    192
    193	temp_asb = *ADFS_SB(sb);
    194	ret = parse_options(sb, &temp_asb, data);
    195	if (ret == 0)
    196		*ADFS_SB(sb) = temp_asb;
    197
    198	return ret;
    199}
    200
    201static int adfs_statfs(struct dentry *dentry, struct kstatfs *buf)
    202{
    203	struct super_block *sb = dentry->d_sb;
    204	struct adfs_sb_info *sbi = ADFS_SB(sb);
    205	u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
    206
    207	adfs_map_statfs(sb, buf);
    208
    209	buf->f_type    = ADFS_SUPER_MAGIC;
    210	buf->f_namelen = sbi->s_namelen;
    211	buf->f_bsize   = sb->s_blocksize;
    212	buf->f_ffree   = (long)(buf->f_bfree * buf->f_files) / (long)buf->f_blocks;
    213	buf->f_fsid    = u64_to_fsid(id);
    214
    215	return 0;
    216}
    217
    218static struct kmem_cache *adfs_inode_cachep;
    219
    220static struct inode *adfs_alloc_inode(struct super_block *sb)
    221{
    222	struct adfs_inode_info *ei;
    223	ei = alloc_inode_sb(sb, adfs_inode_cachep, GFP_KERNEL);
    224	if (!ei)
    225		return NULL;
    226	return &ei->vfs_inode;
    227}
    228
    229static void adfs_free_inode(struct inode *inode)
    230{
    231	kmem_cache_free(adfs_inode_cachep, ADFS_I(inode));
    232}
    233
    234static int adfs_drop_inode(struct inode *inode)
    235{
    236	/* always drop inodes if we are read-only */
    237	return !IS_ENABLED(CONFIG_ADFS_FS_RW) || IS_RDONLY(inode);
    238}
    239
    240static void init_once(void *foo)
    241{
    242	struct adfs_inode_info *ei = (struct adfs_inode_info *) foo;
    243
    244	inode_init_once(&ei->vfs_inode);
    245}
    246
    247static int __init init_inodecache(void)
    248{
    249	adfs_inode_cachep = kmem_cache_create("adfs_inode_cache",
    250					     sizeof(struct adfs_inode_info),
    251					     0, (SLAB_RECLAIM_ACCOUNT|
    252						SLAB_MEM_SPREAD|SLAB_ACCOUNT),
    253					     init_once);
    254	if (adfs_inode_cachep == NULL)
    255		return -ENOMEM;
    256	return 0;
    257}
    258
    259static void destroy_inodecache(void)
    260{
    261	/*
    262	 * Make sure all delayed rcu free inodes are flushed before we
    263	 * destroy cache.
    264	 */
    265	rcu_barrier();
    266	kmem_cache_destroy(adfs_inode_cachep);
    267}
    268
    269static const struct super_operations adfs_sops = {
    270	.alloc_inode	= adfs_alloc_inode,
    271	.free_inode	= adfs_free_inode,
    272	.drop_inode	= adfs_drop_inode,
    273	.write_inode	= adfs_write_inode,
    274	.put_super	= adfs_put_super,
    275	.statfs		= adfs_statfs,
    276	.remount_fs	= adfs_remount,
    277	.show_options	= adfs_show_options,
    278};
    279
    280static int adfs_probe(struct super_block *sb, unsigned int offset, int silent,
    281		      int (*validate)(struct super_block *sb,
    282				      struct buffer_head *bh,
    283				      struct adfs_discrecord **bhp))
    284{
    285	struct adfs_sb_info *asb = ADFS_SB(sb);
    286	struct adfs_discrecord *dr;
    287	struct buffer_head *bh;
    288	unsigned int blocksize = BLOCK_SIZE;
    289	int ret, try;
    290
    291	for (try = 0; try < 2; try++) {
    292		/* try to set the requested block size */
    293		if (sb->s_blocksize != blocksize &&
    294		    !sb_set_blocksize(sb, blocksize)) {
    295			if (!silent)
    296				adfs_msg(sb, KERN_ERR,
    297					 "error: unsupported blocksize");
    298			return -EINVAL;
    299		}
    300
    301		/* read the buffer */
    302		bh = sb_bread(sb, offset >> sb->s_blocksize_bits);
    303		if (!bh) {
    304			adfs_msg(sb, KERN_ERR,
    305				 "error: unable to read block %u, try %d",
    306				 offset >> sb->s_blocksize_bits, try);
    307			return -EIO;
    308		}
    309
    310		/* validate it */
    311		ret = validate(sb, bh, &dr);
    312		if (ret) {
    313			brelse(bh);
    314			return ret;
    315		}
    316
    317		/* does the block size match the filesystem block size? */
    318		blocksize = 1 << dr->log2secsize;
    319		if (sb->s_blocksize == blocksize) {
    320			asb->s_map = adfs_read_map(sb, dr);
    321			brelse(bh);
    322			return PTR_ERR_OR_ZERO(asb->s_map);
    323		}
    324
    325		brelse(bh);
    326	}
    327
    328	return -EIO;
    329}
    330
    331static int adfs_validate_bblk(struct super_block *sb, struct buffer_head *bh,
    332			      struct adfs_discrecord **drp)
    333{
    334	struct adfs_discrecord *dr;
    335	unsigned char *b_data;
    336
    337	b_data = bh->b_data + (ADFS_DISCRECORD % sb->s_blocksize);
    338	if (adfs_checkbblk(b_data))
    339		return -EILSEQ;
    340
    341	/* Do some sanity checks on the ADFS disc record */
    342	dr = (struct adfs_discrecord *)(b_data + ADFS_DR_OFFSET);
    343	if (adfs_checkdiscrecord(dr))
    344		return -EILSEQ;
    345
    346	*drp = dr;
    347	return 0;
    348}
    349
    350static int adfs_validate_dr0(struct super_block *sb, struct buffer_head *bh,
    351			      struct adfs_discrecord **drp)
    352{
    353	struct adfs_discrecord *dr;
    354
    355	/* Do some sanity checks on the ADFS disc record */
    356	dr = (struct adfs_discrecord *)(bh->b_data + 4);
    357	if (adfs_checkdiscrecord(dr) || dr->nzones_high || dr->nzones != 1)
    358		return -EILSEQ;
    359
    360	*drp = dr;
    361	return 0;
    362}
    363
    364static int adfs_fill_super(struct super_block *sb, void *data, int silent)
    365{
    366	struct adfs_discrecord *dr;
    367	struct object_info root_obj;
    368	struct adfs_sb_info *asb;
    369	struct inode *root;
    370	int ret = -EINVAL;
    371
    372	sb->s_flags |= ADFS_SB_FLAGS;
    373
    374	asb = kzalloc(sizeof(*asb), GFP_KERNEL);
    375	if (!asb)
    376		return -ENOMEM;
    377
    378	sb->s_fs_info = asb;
    379	sb->s_magic = ADFS_SUPER_MAGIC;
    380	sb->s_time_gran = 10000000;
    381
    382	/* set default options */
    383	asb->s_uid = GLOBAL_ROOT_UID;
    384	asb->s_gid = GLOBAL_ROOT_GID;
    385	asb->s_owner_mask = ADFS_DEFAULT_OWNER_MASK;
    386	asb->s_other_mask = ADFS_DEFAULT_OTHER_MASK;
    387	asb->s_ftsuffix = 0;
    388
    389	if (parse_options(sb, asb, data))
    390		goto error;
    391
    392	/* Try to probe the filesystem boot block */
    393	ret = adfs_probe(sb, ADFS_DISCRECORD, 1, adfs_validate_bblk);
    394	if (ret == -EILSEQ)
    395		ret = adfs_probe(sb, 0, silent, adfs_validate_dr0);
    396	if (ret == -EILSEQ) {
    397		if (!silent)
    398			adfs_msg(sb, KERN_ERR,
    399				 "error: can't find an ADFS filesystem on dev %s.",
    400				 sb->s_id);
    401		ret = -EINVAL;
    402	}
    403	if (ret)
    404		goto error;
    405
    406	/* set up enough so that we can read an inode */
    407	sb->s_op = &adfs_sops;
    408
    409	dr = adfs_map_discrecord(asb->s_map);
    410
    411	root_obj.parent_id = root_obj.indaddr = le32_to_cpu(dr->root);
    412	root_obj.name_len  = 0;
    413	/* Set root object date as 01 Jan 1987 00:00:00 */
    414	root_obj.loadaddr  = 0xfff0003f;
    415	root_obj.execaddr  = 0xec22c000;
    416	root_obj.size	   = ADFS_NEWDIR_SIZE;
    417	root_obj.attr	   = ADFS_NDA_DIRECTORY   | ADFS_NDA_OWNER_READ |
    418			     ADFS_NDA_OWNER_WRITE | ADFS_NDA_PUBLIC_READ;
    419
    420	/*
    421	 * If this is a F+ disk with variable length directories,
    422	 * get the root_size from the disc record.
    423	 */
    424	if (dr->format_version) {
    425		root_obj.size = le32_to_cpu(dr->root_size);
    426		asb->s_dir     = &adfs_fplus_dir_ops;
    427		asb->s_namelen = ADFS_FPLUS_NAME_LEN;
    428	} else {
    429		asb->s_dir     = &adfs_f_dir_ops;
    430		asb->s_namelen = ADFS_F_NAME_LEN;
    431	}
    432	/*
    433	 * ,xyz hex filetype suffix may be added by driver
    434	 * to files that have valid RISC OS filetype
    435	 */
    436	if (asb->s_ftsuffix)
    437		asb->s_namelen += 4;
    438
    439	sb->s_d_op = &adfs_dentry_operations;
    440	root = adfs_iget(sb, &root_obj);
    441	sb->s_root = d_make_root(root);
    442	if (!sb->s_root) {
    443		adfs_free_map(sb);
    444		adfs_error(sb, "get root inode failed\n");
    445		ret = -EIO;
    446		goto error;
    447	}
    448	return 0;
    449
    450error:
    451	sb->s_fs_info = NULL;
    452	kfree(asb);
    453	return ret;
    454}
    455
    456static struct dentry *adfs_mount(struct file_system_type *fs_type,
    457	int flags, const char *dev_name, void *data)
    458{
    459	return mount_bdev(fs_type, flags, dev_name, data, adfs_fill_super);
    460}
    461
    462static struct file_system_type adfs_fs_type = {
    463	.owner		= THIS_MODULE,
    464	.name		= "adfs",
    465	.mount		= adfs_mount,
    466	.kill_sb	= kill_block_super,
    467	.fs_flags	= FS_REQUIRES_DEV,
    468};
    469MODULE_ALIAS_FS("adfs");
    470
    471static int __init init_adfs_fs(void)
    472{
    473	int err = init_inodecache();
    474	if (err)
    475		goto out1;
    476	err = register_filesystem(&adfs_fs_type);
    477	if (err)
    478		goto out;
    479	return 0;
    480out:
    481	destroy_inodecache();
    482out1:
    483	return err;
    484}
    485
    486static void __exit exit_adfs_fs(void)
    487{
    488	unregister_filesystem(&adfs_fs_type);
    489	destroy_inodecache();
    490}
    491
    492module_init(init_adfs_fs)
    493module_exit(exit_adfs_fs)
    494MODULE_LICENSE("GPL");