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

Attachment: pEpkey.asc
Description: application/pgp-keys

_______________________________________________
vbox-dev mailing list
[email protected]
https://www.virtualbox.org/mailman/listinfo/vbox-dev

Reply via email to