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 (11495B)


      1// SPDX-License-Identifier: MIT
      2/*
      3 * VirtualBox Guest Shared Folders support: Virtual File System.
      4 *
      5 * Module initialization/finalization
      6 * File system registration/deregistration
      7 * Superblock reading
      8 * Few utility functions
      9 *
     10 * Copyright (C) 2006-2018 Oracle Corporation
     11 */
     12
     13#include <linux/idr.h>
     14#include <linux/fs_parser.h>
     15#include <linux/magic.h>
     16#include <linux/module.h>
     17#include <linux/nls.h>
     18#include <linux/statfs.h>
     19#include <linux/vbox_utils.h>
     20#include "vfsmod.h"
     21
     22#define VBOXSF_SUPER_MAGIC 0x786f4256 /* 'VBox' little endian */
     23
     24static const unsigned char VBSF_MOUNT_SIGNATURE[4] = "\000\377\376\375";
     25
     26static int follow_symlinks;
     27module_param(follow_symlinks, int, 0444);
     28MODULE_PARM_DESC(follow_symlinks,
     29		 "Let host resolve symlinks rather than showing them");
     30
     31static DEFINE_IDA(vboxsf_bdi_ida);
     32static DEFINE_MUTEX(vboxsf_setup_mutex);
     33static bool vboxsf_setup_done;
     34static struct super_operations vboxsf_super_ops; /* forward declaration */
     35static struct kmem_cache *vboxsf_inode_cachep;
     36
     37static char * const vboxsf_default_nls = CONFIG_NLS_DEFAULT;
     38
     39enum  { opt_nls, opt_uid, opt_gid, opt_ttl, opt_dmode, opt_fmode,
     40	opt_dmask, opt_fmask };
     41
     42static const struct fs_parameter_spec vboxsf_fs_parameters[] = {
     43	fsparam_string	("nls",		opt_nls),
     44	fsparam_u32	("uid",		opt_uid),
     45	fsparam_u32	("gid",		opt_gid),
     46	fsparam_u32	("ttl",		opt_ttl),
     47	fsparam_u32oct	("dmode",	opt_dmode),
     48	fsparam_u32oct	("fmode",	opt_fmode),
     49	fsparam_u32oct	("dmask",	opt_dmask),
     50	fsparam_u32oct	("fmask",	opt_fmask),
     51	{}
     52};
     53
     54static int vboxsf_parse_param(struct fs_context *fc, struct fs_parameter *param)
     55{
     56	struct vboxsf_fs_context *ctx = fc->fs_private;
     57	struct fs_parse_result result;
     58	kuid_t uid;
     59	kgid_t gid;
     60	int opt;
     61
     62	opt = fs_parse(fc, vboxsf_fs_parameters, param, &result);
     63	if (opt < 0)
     64		return opt;
     65
     66	switch (opt) {
     67	case opt_nls:
     68		if (ctx->nls_name || fc->purpose != FS_CONTEXT_FOR_MOUNT) {
     69			vbg_err("vboxsf: Cannot reconfigure nls option\n");
     70			return -EINVAL;
     71		}
     72		ctx->nls_name = param->string;
     73		param->string = NULL;
     74		break;
     75	case opt_uid:
     76		uid = make_kuid(current_user_ns(), result.uint_32);
     77		if (!uid_valid(uid))
     78			return -EINVAL;
     79		ctx->o.uid = uid;
     80		break;
     81	case opt_gid:
     82		gid = make_kgid(current_user_ns(), result.uint_32);
     83		if (!gid_valid(gid))
     84			return -EINVAL;
     85		ctx->o.gid = gid;
     86		break;
     87	case opt_ttl:
     88		ctx->o.ttl = msecs_to_jiffies(result.uint_32);
     89		break;
     90	case opt_dmode:
     91		if (result.uint_32 & ~0777)
     92			return -EINVAL;
     93		ctx->o.dmode = result.uint_32;
     94		ctx->o.dmode_set = true;
     95		break;
     96	case opt_fmode:
     97		if (result.uint_32 & ~0777)
     98			return -EINVAL;
     99		ctx->o.fmode = result.uint_32;
    100		ctx->o.fmode_set = true;
    101		break;
    102	case opt_dmask:
    103		if (result.uint_32 & ~07777)
    104			return -EINVAL;
    105		ctx->o.dmask = result.uint_32;
    106		break;
    107	case opt_fmask:
    108		if (result.uint_32 & ~07777)
    109			return -EINVAL;
    110		ctx->o.fmask = result.uint_32;
    111		break;
    112	default:
    113		return -EINVAL;
    114	}
    115
    116	return 0;
    117}
    118
    119static int vboxsf_fill_super(struct super_block *sb, struct fs_context *fc)
    120{
    121	struct vboxsf_fs_context *ctx = fc->fs_private;
    122	struct shfl_string *folder_name, root_path;
    123	struct vboxsf_sbi *sbi;
    124	struct dentry *droot;
    125	struct inode *iroot;
    126	char *nls_name;
    127	size_t size;
    128	int err;
    129
    130	if (!fc->source)
    131		return -EINVAL;
    132
    133	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
    134	if (!sbi)
    135		return -ENOMEM;
    136
    137	sbi->o = ctx->o;
    138	idr_init(&sbi->ino_idr);
    139	spin_lock_init(&sbi->ino_idr_lock);
    140	sbi->next_generation = 1;
    141	sbi->bdi_id = -1;
    142
    143	/* Load nls if not utf8 */
    144	nls_name = ctx->nls_name ? ctx->nls_name : vboxsf_default_nls;
    145	if (strcmp(nls_name, "utf8") != 0) {
    146		if (nls_name == vboxsf_default_nls)
    147			sbi->nls = load_nls_default();
    148		else
    149			sbi->nls = load_nls(nls_name);
    150
    151		if (!sbi->nls) {
    152			vbg_err("vboxsf: Count not load '%s' nls\n", nls_name);
    153			err = -EINVAL;
    154			goto fail_free;
    155		}
    156	}
    157
    158	sbi->bdi_id = ida_simple_get(&vboxsf_bdi_ida, 0, 0, GFP_KERNEL);
    159	if (sbi->bdi_id < 0) {
    160		err = sbi->bdi_id;
    161		goto fail_free;
    162	}
    163
    164	err = super_setup_bdi_name(sb, "vboxsf-%d", sbi->bdi_id);
    165	if (err)
    166		goto fail_free;
    167	sb->s_bdi->ra_pages = 0;
    168	sb->s_bdi->io_pages = 0;
    169
    170	/* Turn source into a shfl_string and map the folder */
    171	size = strlen(fc->source) + 1;
    172	folder_name = kmalloc(SHFLSTRING_HEADER_SIZE + size, GFP_KERNEL);
    173	if (!folder_name) {
    174		err = -ENOMEM;
    175		goto fail_free;
    176	}
    177	folder_name->size = size;
    178	folder_name->length = size - 1;
    179	strlcpy(folder_name->string.utf8, fc->source, size);
    180	err = vboxsf_map_folder(folder_name, &sbi->root);
    181	kfree(folder_name);
    182	if (err) {
    183		vbg_err("vboxsf: Host rejected mount of '%s' with error %d\n",
    184			fc->source, err);
    185		goto fail_free;
    186	}
    187
    188	root_path.length = 1;
    189	root_path.size = 2;
    190	root_path.string.utf8[0] = '/';
    191	root_path.string.utf8[1] = 0;
    192	err = vboxsf_stat(sbi, &root_path, &sbi->root_info);
    193	if (err)
    194		goto fail_unmap;
    195
    196	sb->s_magic = VBOXSF_SUPER_MAGIC;
    197	sb->s_blocksize = 1024;
    198	sb->s_maxbytes = MAX_LFS_FILESIZE;
    199	sb->s_op = &vboxsf_super_ops;
    200	sb->s_d_op = &vboxsf_dentry_ops;
    201
    202	iroot = iget_locked(sb, 0);
    203	if (!iroot) {
    204		err = -ENOMEM;
    205		goto fail_unmap;
    206	}
    207	vboxsf_init_inode(sbi, iroot, &sbi->root_info, false);
    208	unlock_new_inode(iroot);
    209
    210	droot = d_make_root(iroot);
    211	if (!droot) {
    212		err = -ENOMEM;
    213		goto fail_unmap;
    214	}
    215
    216	sb->s_root = droot;
    217	sb->s_fs_info = sbi;
    218	return 0;
    219
    220fail_unmap:
    221	vboxsf_unmap_folder(sbi->root);
    222fail_free:
    223	if (sbi->bdi_id >= 0)
    224		ida_simple_remove(&vboxsf_bdi_ida, sbi->bdi_id);
    225	if (sbi->nls)
    226		unload_nls(sbi->nls);
    227	idr_destroy(&sbi->ino_idr);
    228	kfree(sbi);
    229	return err;
    230}
    231
    232static void vboxsf_inode_init_once(void *data)
    233{
    234	struct vboxsf_inode *sf_i = data;
    235
    236	mutex_init(&sf_i->handle_list_mutex);
    237	inode_init_once(&sf_i->vfs_inode);
    238}
    239
    240static struct inode *vboxsf_alloc_inode(struct super_block *sb)
    241{
    242	struct vboxsf_inode *sf_i;
    243
    244	sf_i = alloc_inode_sb(sb, vboxsf_inode_cachep, GFP_NOFS);
    245	if (!sf_i)
    246		return NULL;
    247
    248	sf_i->force_restat = 0;
    249	INIT_LIST_HEAD(&sf_i->handle_list);
    250
    251	return &sf_i->vfs_inode;
    252}
    253
    254static void vboxsf_free_inode(struct inode *inode)
    255{
    256	struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb);
    257	unsigned long flags;
    258
    259	spin_lock_irqsave(&sbi->ino_idr_lock, flags);
    260	idr_remove(&sbi->ino_idr, inode->i_ino);
    261	spin_unlock_irqrestore(&sbi->ino_idr_lock, flags);
    262	kmem_cache_free(vboxsf_inode_cachep, VBOXSF_I(inode));
    263}
    264
    265static void vboxsf_put_super(struct super_block *sb)
    266{
    267	struct vboxsf_sbi *sbi = VBOXSF_SBI(sb);
    268
    269	vboxsf_unmap_folder(sbi->root);
    270	if (sbi->bdi_id >= 0)
    271		ida_simple_remove(&vboxsf_bdi_ida, sbi->bdi_id);
    272	if (sbi->nls)
    273		unload_nls(sbi->nls);
    274
    275	/*
    276	 * vboxsf_free_inode uses the idr, make sure all delayed rcu free
    277	 * inodes are flushed.
    278	 */
    279	rcu_barrier();
    280	idr_destroy(&sbi->ino_idr);
    281	kfree(sbi);
    282}
    283
    284static int vboxsf_statfs(struct dentry *dentry, struct kstatfs *stat)
    285{
    286	struct super_block *sb = dentry->d_sb;
    287	struct shfl_volinfo shfl_volinfo;
    288	struct vboxsf_sbi *sbi;
    289	u32 buf_len;
    290	int err;
    291
    292	sbi = VBOXSF_SBI(sb);
    293	buf_len = sizeof(shfl_volinfo);
    294	err = vboxsf_fsinfo(sbi->root, 0, SHFL_INFO_GET | SHFL_INFO_VOLUME,
    295			    &buf_len, &shfl_volinfo);
    296	if (err)
    297		return err;
    298
    299	stat->f_type = VBOXSF_SUPER_MAGIC;
    300	stat->f_bsize = shfl_volinfo.bytes_per_allocation_unit;
    301
    302	do_div(shfl_volinfo.total_allocation_bytes,
    303	       shfl_volinfo.bytes_per_allocation_unit);
    304	stat->f_blocks = shfl_volinfo.total_allocation_bytes;
    305
    306	do_div(shfl_volinfo.available_allocation_bytes,
    307	       shfl_volinfo.bytes_per_allocation_unit);
    308	stat->f_bfree  = shfl_volinfo.available_allocation_bytes;
    309	stat->f_bavail = shfl_volinfo.available_allocation_bytes;
    310
    311	stat->f_files = 1000;
    312	/*
    313	 * Don't return 0 here since the guest may then think that it is not
    314	 * possible to create any more files.
    315	 */
    316	stat->f_ffree = 1000000;
    317	stat->f_fsid.val[0] = 0;
    318	stat->f_fsid.val[1] = 0;
    319	stat->f_namelen = 255;
    320	return 0;
    321}
    322
    323static struct super_operations vboxsf_super_ops = {
    324	.alloc_inode	= vboxsf_alloc_inode,
    325	.free_inode	= vboxsf_free_inode,
    326	.put_super	= vboxsf_put_super,
    327	.statfs		= vboxsf_statfs,
    328};
    329
    330static int vboxsf_setup(void)
    331{
    332	int err;
    333
    334	mutex_lock(&vboxsf_setup_mutex);
    335
    336	if (vboxsf_setup_done)
    337		goto success;
    338
    339	vboxsf_inode_cachep =
    340		kmem_cache_create("vboxsf_inode_cache",
    341				  sizeof(struct vboxsf_inode), 0,
    342				  (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD |
    343				   SLAB_ACCOUNT),
    344				  vboxsf_inode_init_once);
    345	if (!vboxsf_inode_cachep) {
    346		err = -ENOMEM;
    347		goto fail_nomem;
    348	}
    349
    350	err = vboxsf_connect();
    351	if (err) {
    352		vbg_err("vboxsf: err %d connecting to guest PCI-device\n", err);
    353		vbg_err("vboxsf: make sure you are inside a VirtualBox VM\n");
    354		vbg_err("vboxsf: and check dmesg for vboxguest errors\n");
    355		goto fail_free_cache;
    356	}
    357
    358	err = vboxsf_set_utf8();
    359	if (err) {
    360		vbg_err("vboxsf_setutf8 error %d\n", err);
    361		goto fail_disconnect;
    362	}
    363
    364	if (!follow_symlinks) {
    365		err = vboxsf_set_symlinks();
    366		if (err)
    367			vbg_warn("vboxsf: Unable to show symlinks: %d\n", err);
    368	}
    369
    370	vboxsf_setup_done = true;
    371success:
    372	mutex_unlock(&vboxsf_setup_mutex);
    373	return 0;
    374
    375fail_disconnect:
    376	vboxsf_disconnect();
    377fail_free_cache:
    378	kmem_cache_destroy(vboxsf_inode_cachep);
    379fail_nomem:
    380	mutex_unlock(&vboxsf_setup_mutex);
    381	return err;
    382}
    383
    384static int vboxsf_parse_monolithic(struct fs_context *fc, void *data)
    385{
    386	if (data && !memcmp(data, VBSF_MOUNT_SIGNATURE, 4)) {
    387		vbg_err("vboxsf: Old binary mount data not supported, remove obsolete mount.vboxsf and/or update your VBoxService.\n");
    388		return -EINVAL;
    389	}
    390
    391	return generic_parse_monolithic(fc, data);
    392}
    393
    394static int vboxsf_get_tree(struct fs_context *fc)
    395{
    396	int err;
    397
    398	err = vboxsf_setup();
    399	if (err)
    400		return err;
    401
    402	return get_tree_nodev(fc, vboxsf_fill_super);
    403}
    404
    405static int vboxsf_reconfigure(struct fs_context *fc)
    406{
    407	struct vboxsf_sbi *sbi = VBOXSF_SBI(fc->root->d_sb);
    408	struct vboxsf_fs_context *ctx = fc->fs_private;
    409	struct inode *iroot = fc->root->d_sb->s_root->d_inode;
    410
    411	/* Apply changed options to the root inode */
    412	sbi->o = ctx->o;
    413	vboxsf_init_inode(sbi, iroot, &sbi->root_info, true);
    414
    415	return 0;
    416}
    417
    418static void vboxsf_free_fc(struct fs_context *fc)
    419{
    420	struct vboxsf_fs_context *ctx = fc->fs_private;
    421
    422	kfree(ctx->nls_name);
    423	kfree(ctx);
    424}
    425
    426static const struct fs_context_operations vboxsf_context_ops = {
    427	.free			= vboxsf_free_fc,
    428	.parse_param		= vboxsf_parse_param,
    429	.parse_monolithic	= vboxsf_parse_monolithic,
    430	.get_tree		= vboxsf_get_tree,
    431	.reconfigure		= vboxsf_reconfigure,
    432};
    433
    434static int vboxsf_init_fs_context(struct fs_context *fc)
    435{
    436	struct vboxsf_fs_context *ctx;
    437
    438	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
    439	if (!ctx)
    440		return -ENOMEM;
    441
    442	current_uid_gid(&ctx->o.uid, &ctx->o.gid);
    443
    444	fc->fs_private = ctx;
    445	fc->ops = &vboxsf_context_ops;
    446	return 0;
    447}
    448
    449static struct file_system_type vboxsf_fs_type = {
    450	.owner			= THIS_MODULE,
    451	.name			= "vboxsf",
    452	.init_fs_context	= vboxsf_init_fs_context,
    453	.kill_sb		= kill_anon_super
    454};
    455
    456/* Module initialization/finalization handlers */
    457static int __init vboxsf_init(void)
    458{
    459	return register_filesystem(&vboxsf_fs_type);
    460}
    461
    462static void __exit vboxsf_fini(void)
    463{
    464	unregister_filesystem(&vboxsf_fs_type);
    465
    466	mutex_lock(&vboxsf_setup_mutex);
    467	if (vboxsf_setup_done) {
    468		vboxsf_disconnect();
    469		/*
    470		 * Make sure all delayed rcu free inodes are flushed
    471		 * before we destroy the cache.
    472		 */
    473		rcu_barrier();
    474		kmem_cache_destroy(vboxsf_inode_cachep);
    475	}
    476	mutex_unlock(&vboxsf_setup_mutex);
    477}
    478
    479module_init(vboxsf_init);
    480module_exit(vboxsf_fini);
    481
    482MODULE_DESCRIPTION("Oracle VM VirtualBox Module for Host File System Access");
    483MODULE_AUTHOR("Oracle Corporation");
    484MODULE_LICENSE("GPL v2");
    485MODULE_ALIAS_FS("vboxsf");