Without the allow_other mount option, no user (not even root) but the one who started qemu/the storage daemon can access the export. Allow users to configure the export such that such accesses are possible.
When we do pass allow_other, we should also pass default_permissions, because our export code performs no permission checks. With default_permissions, we can just let the kernel do it. Signed-off-by: Max Reitz <mre...@redhat.com> --- qapi/block-export.json | 11 ++++++++++- block/export/fuse.c | 17 +++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/qapi/block-export.json b/qapi/block-export.json index e819e70cac..5d1cc04ac4 100644 --- a/qapi/block-export.json +++ b/qapi/block-export.json @@ -132,11 +132,20 @@ # @growable: Whether writes beyond the EOF should grow the block node # accordingly. (default: false) # +# @allow-other: By default (if this is false), only qemu's user is allowed +# access to this export. That cannot be changed even with +# chmod or chown. +# This option will allow other users access to the export with the +# FUSE mount options "allow_other,default_permissions". +# (default_permissions enables standard UNIX permission checks.) +# (since 6.1; default: false) +# # Since: 6.0 ## { 'struct': 'BlockExportOptionsFuse', 'data': { 'mountpoint': 'str', - '*growable': 'bool' }, + '*growable': 'bool', + '*allow-other': 'bool' }, 'if': 'defined(CONFIG_FUSE)' } ## diff --git a/block/export/fuse.c b/block/export/fuse.c index 38f74c94da..34a5836ece 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -46,6 +46,7 @@ typedef struct FuseExport { char *mountpoint; bool writable; bool growable; + bool allow_other; } FuseExport; static GHashTable *exports; @@ -117,6 +118,7 @@ static int fuse_export_create(BlockExport *blk_exp, exp->mountpoint = g_strdup(args->mountpoint); exp->writable = blk_exp_args->writable; exp->growable = args->growable; + exp->allow_other = args->allow_other; ret = setup_fuse_export(exp, args->mountpoint, errp); if (ret < 0) { @@ -150,11 +152,22 @@ static int setup_fuse_export(FuseExport *exp, const char *mountpoint, { const char *fuse_argv[4]; char *mount_opts; + const char *allow_other; struct fuse_args fuse_args; int ret; - /* Needs to match what fuse_init() sets. Only max_read must be supplied. */ - mount_opts = g_strdup_printf("max_read=%zu", FUSE_MAX_BOUNCE_BYTES); + if (exp->allow_other) { + allow_other = ",allow_other,default_permissions"; + } else { + allow_other = ""; + } + + /* + * max_read needs to match what fuse_init() sets. + * max_write need not be supplied. + */ + mount_opts = g_strdup_printf("max_read=%zu%s", FUSE_MAX_BOUNCE_BYTES, + allow_other); fuse_argv[0] = ""; /* Dummy program name */ fuse_argv[1] = "-o"; -- 2.31.1