mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:10 +00:00
fuse: Fix mount options
Since I actually took a look into how mounting with libfuse works[1], I
now know that the FUSE mount options are not exactly standard mount
system call options. Specifically:
- We should add "nosuid,nodev,noatime" because that is going to be
translated into the respective MS_ mount flags; and those flags make
sense for us.
- We can set rw/ro to make the mount writable or not. It makes sense to
set this flag to produce a better error message for read-only exports
(EROFS instead of EACCES).
This changes behavior as can be seen in iotest 308: It is no longer
possible to modify metadata of read-only exports.
Similarly, in fuse-allow-other, we must now make the export writable
to use SETATTR.
In addition, in the comment, we can note that the FUSE mount() system
call actually expects some more parameters that we can omit because
fusermount3 (i.e. libfuse) will figure them out by itself:
- fd: /dev/fuse fd
- rootmode: Inode mode of the root node
- user_id/group_id: Mounter's UID/GID
[1] It invokes fusermount3, an SUID libfuse helper program, which parses
and processes some mount options before actually invoking the
mount() system call.
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
Message-ID: <20260309150856.26800-8-hreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
committed by
Kevin Wolf
parent
b8b054690c
commit
c2959a8122
@@ -246,10 +246,18 @@ static int mount_fuse_export(FuseExport *exp, Error **errp)
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* max_read needs to match what fuse_init() sets.
|
||||
* max_write need not be supplied.
|
||||
* Note that these mount options differ from what we would pass to a direct
|
||||
* mount() call:
|
||||
* - nosuid, nodev, and noatime are not understood by the kernel; libfuse
|
||||
* uses those options to construct the mount flags (MS_*)
|
||||
* - The FUSE kernel driver requires additional options (fd, rootmode,
|
||||
* user_id, group_id); these will be set by libfuse.
|
||||
* Note that max_read is set here, while max_write is set via the FUSE INIT
|
||||
* operation.
|
||||
*/
|
||||
mount_opts = g_strdup_printf("max_read=%zu,default_permissions%s",
|
||||
mount_opts = g_strdup_printf("%s,nosuid,nodev,noatime,max_read=%zu,"
|
||||
"default_permissions%s",
|
||||
exp->writable ? "rw" : "ro",
|
||||
FUSE_MAX_BOUNCE_BYTES,
|
||||
exp->allow_other ? ",allow_other" : "");
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ stat -c 'Permissions pre-chmod: %a' "$EXT_MP"
|
||||
chmod u+w "$EXT_MP" 2>&1 | _filter_testdir | _filter_imgfmt
|
||||
stat -c 'Permissions post-+w: %a' "$EXT_MP"
|
||||
|
||||
# But that we can set, say, +x (if we are so inclined)
|
||||
# Same for other flags, like, say +x
|
||||
chmod u+x "$EXT_MP" 2>&1 | _filter_testdir | _filter_imgfmt
|
||||
stat -c 'Permissions post-+x: %a' "$EXT_MP"
|
||||
|
||||
@@ -236,7 +236,7 @@ output=$($QEMU_IO -f raw -c 'write -P 42 1M 64k' "$TEST_IMG" 2>&1 \
|
||||
|
||||
# Expected reference output: Opening the file fails because it has no
|
||||
# write permission
|
||||
reference="Could not open 'TEST_DIR/t.IMGFMT': Permission denied"
|
||||
reference="Could not open 'TEST_DIR/t.IMGFMT': Read-only file system"
|
||||
|
||||
if echo "$output" | grep -q "$reference"; then
|
||||
echo "Writing to read-only export failed: OK"
|
||||
|
||||
@@ -53,7 +53,8 @@ Images are identical.
|
||||
Permissions pre-chmod: 400
|
||||
chmod: changing permissions of 'TEST_DIR/t.IMGFMT.fuse': Read-only file system
|
||||
Permissions post-+w: 400
|
||||
Permissions post-+x: 500
|
||||
chmod: changing permissions of 'TEST_DIR/t.IMGFMT.fuse': Read-only file system
|
||||
Permissions post-+x: 400
|
||||
|
||||
=== Mount over existing file ===
|
||||
{'execute': 'block-export-add',
|
||||
|
||||
@@ -101,7 +101,8 @@ run_permission_test()
|
||||
|
||||
fuse_export_add 'export' \
|
||||
"'mountpoint': '$EXT_MP',
|
||||
'allow-other': '$1'"
|
||||
'allow-other': '$1',
|
||||
'writable': true"
|
||||
|
||||
# Should always work
|
||||
echo '(Removing all permissions)'
|
||||
|
||||
@@ -12,7 +12,8 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536
|
||||
'id': 'export',
|
||||
'node-name': 'node-format',
|
||||
'mountpoint': 'TEST_DIR/fuse-export',
|
||||
'allow-other': 'off'
|
||||
'allow-other': 'off',
|
||||
'writable': true
|
||||
} }
|
||||
{"return": {}}
|
||||
(Removing all permissions)
|
||||
@@ -41,7 +42,8 @@ stat: cannot statx 'fuse-export': Permission denied
|
||||
'id': 'export',
|
||||
'node-name': 'node-format',
|
||||
'mountpoint': 'TEST_DIR/fuse-export',
|
||||
'allow-other': 'on'
|
||||
'allow-other': 'on',
|
||||
'writable': true
|
||||
} }
|
||||
{"return": {}}
|
||||
(Removing all permissions)
|
||||
@@ -68,7 +70,8 @@ Permissions seen by nobody: 440
|
||||
'id': 'export',
|
||||
'node-name': 'node-format',
|
||||
'mountpoint': 'TEST_DIR/fuse-export',
|
||||
'allow-other': 'auto'
|
||||
'allow-other': 'auto',
|
||||
'writable': true
|
||||
} }
|
||||
{"return": {}}
|
||||
(Removing all permissions)
|
||||
|
||||
Reference in New Issue
Block a user