04.05.19 16:44, Michael Thayer wrote: > 03.05.19 23:40, Knut St. Osmundsen wrote: > [...] >> Finally, does the libc or kernel mount() implementation somehow invoke >> the /sbin/mount.vboxsf helper tool? Please point me to the code causing >> this, because our vboxsf sources does not parse any parameter strings, >> it is binary struct only. > > The mount(8) manual page reads to me that the mount utility calls the > mount helper (or skips it if you pass "-i"). Our mount helper calls > mount(2) to perform the actual mount. Hans modified the shared folder > kernel code to do the parsing. I suspect the version Sérgio is testing > against has that change as a patch. Sérgio, could you take a look at > that, or point us to the sources you tested against?
Attaching Hans's patch to the kernel driver. This version is from a while back, don't know if it will still apply cleanly. > Regards > Michael > >> Kind regards, bird. >> >> >> On 2019-05-02 6:56 PM, Sérgio Basto wrote: >>> Hi, >>> Please accept this patch we are using on Fedora packages and it is >>> working with in-kernel and not in-kernel (el7) modules >>> >>> I'm OK with MIT license for this patch >>> Best regards >>> _______________________________________________ >>> vbox-dev mailing list >>> [email protected] >>> https://www.virtualbox.org/mailman/listinfo/vbox-dev >> >> >> _______________________________________________ >> vbox-dev mailing list >> [email protected] >> https://www.virtualbox.org/mailman/listinfo/vbox-dev >> > > > _______________________________________________ > vbox-dev mailing list > [email protected] > https://www.virtualbox.org/mailman/listinfo/vbox-dev > -- Michael Thayer | VirtualBox engineer ORACLE Deutschland B.V. & Co. KG | Werkstr. 24 | D-71384 Weinstadt ORACLE Deutschland B.V. & Co. KG Hauptverwaltung: Riesstraße 25, D-80992 München Registergericht: Amtsgericht München, HRA 95603 Komplementärin: ORACLE Deutschland Verwaltung B.V. Hertogswetering 163/167, 3543 AS Utrecht, Niederlande Handelsregister der Handelskammer Midden-Nederland, Nr. 30143697 Geschäftsführer: Alexander van der Ven, Jan Schultheiss, Val Maher
From 1f284b6cd1d44b95eb87edd0e28e414cdb12e97f Mon Sep 17 00:00:00 2001 From: Hans de Goede <[email protected]> Date: Mon, 22 Jan 2018 16:36:44 +0100 Subject: [PATCH] vboxsf: Modify vboxsf to use text only mount options Signed-off-by: Hans de Goede <[email protected]> --- fs/vboxsf/super.c | 282 ++++++++++++++++++++++++----------------- fs/vboxsf/vfsmod.h | 6 +- include/uapi/linux/vbsfmount.h | 62 --------- 3 files changed, 169 insertions(+), 181 deletions(-) delete mode 100644 include/uapi/linux/vbsfmount.h diff --git a/fs/vboxsf/super.c b/fs/vboxsf/super.c index 0de37cb56f29..231a38d08600 100644 --- a/fs/vboxsf/super.c +++ b/fs/vboxsf/super.c @@ -13,104 +13,187 @@ #include <linux/magic.h> #include <linux/module.h> #include <linux/nls.h> +#include <linux/parser.h> #include <linux/statfs.h> #include <linux/vbox_utils.h> -#include <linux/vbsfmount.h> #include "vfsmod.h" -MODULE_DESCRIPTION("Oracle VM VirtualBox Module for Host File System Access"); -MODULE_AUTHOR("Oracle Corporation"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS_FS("vboxsf"); +#define VBSF_MOUNT_SIGNATURE_BYTE_0 '\000' +#define VBSF_MOUNT_SIGNATURE_BYTE_1 '\377' +#define VBSF_MOUNT_SIGNATURE_BYTE_2 '\376' +#define VBSF_MOUNT_SIGNATURE_BYTE_3 '\375' + +static int follow_symlinks; +module_param(follow_symlinks, int, 0444); +MODULE_PARM_DESC(follow_symlinks, + "Let host resolve symlinks rather than showing them"); static struct super_operations sf_super_ops; /* forward declaration */ static struct kmem_cache *sf_inode_cachep; +char * const vboxsf_default_nls = "utf8"; + +enum { opt_name, opt_nls, opt_uid, opt_gid, opt_ttl, opt_dmode, opt_fmode, + opt_dmask, opt_fmask, opt_error }; + +static const match_table_t vboxsf_tokens = { + { opt_name, "name=%s" }, + { opt_nls, "nls=%" }, + { opt_uid, "uid=%u" }, + { opt_gid, "gid=%u" }, + { opt_ttl, "ttl=%u" }, + { opt_dmode, "dmode=%o" }, + { opt_fmode, "fmode=%o" }, + { opt_dmask, "dmask=%o" }, + { opt_fmask, "fmask=%o" }, + { opt_error, NULL }, +}; + +static int vboxsf_parse_options(struct sf_glob_info *sf_g, char *options) +{ + substring_t args[MAX_OPT_ARGS]; + int value, token; + size_t size; + char *p; + + if (!options) + goto out; + + if (options[0] == VBSF_MOUNT_SIGNATURE_BYTE_0 && + options[1] == VBSF_MOUNT_SIGNATURE_BYTE_1 && + options[2] == VBSF_MOUNT_SIGNATURE_BYTE_2 && + options[3] == VBSF_MOUNT_SIGNATURE_BYTE_3) { + vbg_err("vboxsf: Old binary mount data not supported, remove obsolete mount.vboxsf and/or update your VBoxService.\n"); + return -EINVAL; + } + + while ((p = strsep(&options, ",")) != NULL) { + if (!*p) + continue; + + token = match_token(p, vboxsf_tokens, args); + switch (token) { + case opt_name: + if (sf_g->name) { + vbg_err("vboxsf: Cannot change mount name\n"); + return -EINVAL; + } + size = args[0].to - args[0].from + 1; + sf_g->name = kmalloc(SHFLSTRING_HEADER_SIZE + size, + GFP_KERNEL); + if (!sf_g->name) + return -ENOMEM; + sf_g->name->size = size; + sf_g->name->length = size - 1; + match_strlcpy(sf_g->name->string.utf8, &args[0], size); + break; + case opt_nls: + if (sf_g->nls_name) { + vbg_err("vboxsf: Cannot change nls option\n"); + return -EINVAL; + } + sf_g->nls_name = match_strdup(&args[0]); + if (!sf_g->nls_name) + return -ENOMEM; + break; + case opt_uid: + if (match_int(&args[0], &value)) + return -EINVAL; + sf_g->uid = value; + break; + case opt_gid: + if (match_int(&args[0], &value)) + return -EINVAL; + sf_g->gid = value; + break; + case opt_ttl: + if (match_int(&args[0], &value)) + return -EINVAL; + sf_g->ttl = msecs_to_jiffies(value); + break; + case opt_dmode: + if (match_octal(&args[0], &value)) + return -EINVAL; + sf_g->dmode = value; + break; + case opt_fmode: + if (match_octal(&args[0], &value)) + return -EINVAL; + sf_g->fmode = value; + break; + case opt_dmask: + if (match_octal(&args[0], &value)) + return -EINVAL; + sf_g->dmask = value; + break; + case opt_fmask: + if (match_octal(&args[0], &value)) + return -EINVAL; + sf_g->fmask = value; + break; + default: + vbg_err("vboxsf: Unrecognized mount option \"%s\" or missing value\n", + p); + return -EINVAL; + } + } + +out: + if (!sf_g->name) { + vbg_err("vboxsf: mount name option is mandatory\n"); + return -EINVAL; + } + + if (!sf_g->nls_name) + sf_g->nls_name = vboxsf_default_nls; + + return 0; +} + /* allocate global info, try to map host share */ -static int sf_glob_alloc(struct vbsf_mount_info_new *info, - struct sf_glob_info **sf_gp) +static int sf_glob_alloc(char *options, struct sf_glob_info **sf_gp) { - size_t name_len, str_len; struct sf_glob_info *sf_g; - struct shfl_string *str_name = NULL; -#ifdef CONFIG_NLS_DEFAULT - const char *nls_name = CONFIG_NLS_DEFAULT; -#else - const char *nls_name = ""; -#endif int err; - if (info->nullchar != '\0' || - info->signature[0] != VBSF_MOUNT_SIGNATURE_BYTE_0 || - info->signature[1] != VBSF_MOUNT_SIGNATURE_BYTE_1 || - info->signature[2] != VBSF_MOUNT_SIGNATURE_BYTE_2) - return -EINVAL; - sf_g = kzalloc(sizeof(*sf_g), GFP_KERNEL); if (!sf_g) return -ENOMEM; - info->name[sizeof(info->name) - 1] = 0; - info->nls_name[sizeof(info->nls_name) - 1] = 0; + sf_g->root_path.length = 1; + sf_g->root_path.size = 2; + sf_g->root_path.string.utf8[0] = '/'; + /* ~0 means use whatever the host gives as mode info */ + sf_g->dmode = ~0; + sf_g->fmode = ~0; - name_len = strlen(info->name); - str_len = offsetof(struct shfl_string, string.utf8) + name_len + 1; - - str_name = kmalloc(str_len, GFP_KERNEL); - if (!str_name) { - err = -ENOMEM; + err = vboxsf_parse_options(sf_g, options); + if (err) goto fail; - } - - str_name->length = name_len; - str_name->size = name_len + 1; - memcpy(str_name->string.utf8, info->name, name_len + 1); - - if (info->nls_name[0]) - nls_name = info->nls_name; /* Load nls if not utf8 */ - if (nls_name[0] && strcmp(nls_name, "utf8") != 0) { - sf_g->nls = load_nls(info->nls_name); + if (strcmp(sf_g->nls_name, "utf8") != 0) { + sf_g->nls = load_nls(sf_g->nls_name); if (!sf_g->nls) { err = -EINVAL; goto fail; } - } else { - sf_g->nls = NULL; } - err = vboxsf_map_folder(str_name, &sf_g->root); + err = vboxsf_map_folder(sf_g->name, &sf_g->root); if (err) goto fail; - kfree(str_name); - - sf_g->ttl = info->ttl; - sf_g->uid = info->uid; - sf_g->gid = info->gid; - - if ((size_t)info->length >= sizeof(struct vbsf_mount_info_new)) { - /* new fields */ - sf_g->dmode = info->dmode; - sf_g->fmode = info->fmode; - sf_g->dmask = info->dmask; - sf_g->fmask = info->fmask; - } else { - sf_g->dmode = ~0; - sf_g->fmode = ~0; - } - *sf_gp = sf_g; return 0; fail: if (sf_g->nls) unload_nls(sf_g->nls); - - kfree(str_name); + if (sf_g->nls_name != vboxsf_default_nls) + kfree(sf_g->nls_name); + kfree(sf_g->name); kfree(sf_g); - return err; } @@ -121,7 +204,9 @@ static void sf_glob_free(struct sf_glob_info *sf_g) if (sf_g->nls) unload_nls(sf_g->nls); - + if (sf_g->nls_name != vboxsf_default_nls) + kfree(sf_g->nls_name); + kfree(sf_g->name); kfree(sf_g); } @@ -137,36 +222,20 @@ static void sf_glob_free(struct sf_glob_info *sf_g) */ static int sf_read_super(struct super_block *sb, void *data, int flags) { - struct vbsf_mount_info_new *info = data; - struct shfl_string *path = NULL; struct shfl_fsobjinfo fsinfo; struct sf_glob_info *sf_g; struct dentry *droot; struct inode *iroot; int err; - if (!info) - return -EINVAL; - if (flags & MS_REMOUNT) return -EINVAL; - err = sf_glob_alloc(info, &sf_g); + err = sf_glob_alloc(data, &sf_g); if (err) return err; - path = kmalloc(SHFLSTRING_HEADER_SIZE + 2, GFP_KERNEL); - if (!path) { - err = -ENOMEM; - goto fail; - } - - path->length = 1; - path->size = 2; - path->string.utf8[0] = '/'; - path->string.utf8[1] = 0; - - err = sf_stat(__func__, sf_g, path, &fsinfo, 0); + err = sf_stat(__func__, sf_g, &sf_g->root_path, &fsinfo, 0); if (err) goto fail; @@ -181,7 +250,7 @@ static int sf_read_super(struct super_block *sb, void *data, int flags) goto fail; } - GET_INODE_INFO(iroot)->path = path; + GET_INODE_INFO(iroot)->path = kmemdup(&sf_g->root_path, sizeof(sf_g->root_path), GFP_KERNEL); sf_init_inode(sf_g, iroot, &fsinfo); unlock_new_inode(iroot); @@ -196,7 +265,6 @@ static int sf_read_super(struct super_block *sb, void *data, int flags) return 0; fail: - kfree(path); sf_glob_free(sf_g); return err; } @@ -253,9 +321,8 @@ static void sf_evict_inode(struct inode *inode) */ static void sf_put_super(struct super_block *sb) { - struct sf_glob_info *sf_g; + struct sf_glob_info *sf_g = GET_GLOB_INFO(sb); - sf_g = GET_GLOB_INFO(sb); sf_glob_free(sf_g); } @@ -298,37 +365,22 @@ static int sf_statfs(struct dentry *dentry, struct kstatfs *stat) return 0; } -static int sf_remount_fs(struct super_block *sb, int *flags, char *data) +static int sf_remount_fs(struct super_block *sb, int *flags, char *options) { - struct sf_glob_info *sf_g; - struct sf_inode_info *sf_i; - struct inode *iroot; + struct sf_glob_info *sf_g = GET_GLOB_INFO(sb); struct shfl_fsobjinfo fsinfo; + struct inode *iroot; int err; - sf_g = GET_GLOB_INFO(sb); - if (data && data[0] != 0) { - struct vbsf_mount_info_new *info = - (struct vbsf_mount_info_new *)data; - if (info->signature[0] == VBSF_MOUNT_SIGNATURE_BYTE_0 - && info->signature[1] == VBSF_MOUNT_SIGNATURE_BYTE_1 - && info->signature[2] == VBSF_MOUNT_SIGNATURE_BYTE_2) { - sf_g->uid = info->uid; - sf_g->gid = info->gid; - sf_g->ttl = info->ttl; - sf_g->dmode = info->dmode; - sf_g->fmode = info->fmode; - sf_g->dmask = info->dmask; - sf_g->fmask = info->fmask; - } - } - iroot = ilookup(sb, 0); if (!iroot) return -ENOENT; - sf_i = GET_INODE_INFO(iroot); - err = sf_stat(__func__, sf_g, sf_i->path, &fsinfo, 0); + err = vboxsf_parse_options(sf_g, options); + if (err) + return err; + + err = sf_stat(__func__, sf_g, &sf_g->root_path, &fsinfo, 0); if (err == 0) sf_init_inode(sf_g, iroot, &fsinfo); else @@ -359,22 +411,11 @@ static struct file_system_type vboxsf_fs_type = { .kill_sb = kill_anon_super }; -static int follow_symlinks; -module_param(follow_symlinks, int, 0444); -MODULE_PARM_DESC(follow_symlinks, - "Let host resolve symlinks rather than showing them"); - /* Module initialization/finalization handlers */ static int __init init(void) { int err; - if (sizeof(struct vbsf_mount_info_new) > PAGE_SIZE) { - vbg_err("vboxsf: Mount information structure is too large %zd; Must be less than or equal to %ld\n", - sizeof(struct vbsf_mount_info_new), PAGE_SIZE); - return -EINVAL; - } - sf_inode_cachep = kmem_cache_create("vboxsf_inode_cache", sizeof(struct sf_inode_info), 0, (SLAB_RECLAIM_ACCOUNT| @@ -428,3 +469,8 @@ static void __exit fini(void) module_init(init); module_exit(fini); + +MODULE_DESCRIPTION("Oracle VM VirtualBox Module for Host File System Access"); +MODULE_AUTHOR("Oracle Corporation"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS_FS("vboxsf"); diff --git a/fs/vboxsf/vfsmod.h b/fs/vboxsf/vfsmod.h index 29dd69aacfdc..5ec972c48fc7 100644 --- a/fs/vboxsf/vfsmod.h +++ b/fs/vboxsf/vfsmod.h @@ -22,8 +22,12 @@ /* per-shared folder information */ struct sf_glob_info { - u32 root; + struct shfl_string root_path __aligned(8); struct nls_table *nls; + u32 root; + /* mount options */ + struct shfl_string *name; + char *nls_name; int ttl; int uid; int gid; diff --git a/include/uapi/linux/vbsfmount.h b/include/uapi/linux/vbsfmount.h deleted file mode 100644 index 21aa546a2a64..000000000000 --- a/include/uapi/linux/vbsfmount.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2006-2016 Oracle Corporation - * - * VirtualBox Guest Shared Folders: mount(2) parameter structure. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef VBFS_MOUNT_H -#define VBFS_MOUNT_H - -/* Linux constraints the size of data mount argument to PAGE_SIZE - 1. */ -#define MAX_HOST_NAME 256 -#define MAX_NLS_NAME 32 - -#define VBSF_MOUNT_SIGNATURE_BYTE_0 ('\377') -#define VBSF_MOUNT_SIGNATURE_BYTE_1 ('\376') -#define VBSF_MOUNT_SIGNATURE_BYTE_2 ('\375') - -struct vbsf_mount_info_new { - /* - * The old version of the mount_info struct started with a - * char name[MAX_HOST_NAME] field, where name cannot be '\0'. - * So the new version of the mount_info struct starts with a - * nullchar field which is always 0 so that we can detect and - * reject the old structure being passed. - */ - char nullchar; - char signature[3]; /* signature */ - int length; /* length of the whole structure */ - char name[MAX_HOST_NAME]; /* share name */ - char nls_name[MAX_NLS_NAME]; /* name of an I/O charset */ - int uid; /* user ID for all entries, default 0=root */ - int gid; /* group ID for all entries, default 0=root */ - int ttl; /* time to live */ - int dmode; /* mode for directories if != 0xffffffff */ - int fmode; /* mode for regular files if != 0xffffffff */ - int dmask; /* umask applied to directories */ - int fmask; /* umask applied to regular files */ -}; - -struct vbsf_mount_opts { - int uid; - int gid; - int ttl; - int dmode; - int fmode; - int dmask; - int fmask; - int ronly; - int sloppy; - int noexec; - int nodev; - int nosuid; - int remount; - char nls_name[MAX_NLS_NAME]; - char *convertcp; -}; - -#endif /* vbsfmount.h */ -- 2.14.3
pEpkey.asc
Description: application/pgp-keys
_______________________________________________ vbox-dev mailing list [email protected] https://www.virtualbox.org/mailman/listinfo/vbox-dev
