9pfs: local: Add support for custom fmode/dmode in 9ps mapped security modes
In mapped security modes, files are created with very restrictive permissions (600 for files and 700 for directories). This makes file sharing between virtual machines and users on the host rather complicated. Imagine eg. a group of users that need to access data produced by processes on a virtual machine. Giving those users access to the data will be difficult since the group access mode is always 0. This patch makes the default mode for both files and directories configurable. Existing setups that don't know about the new parameters keep using the current secure behavior. Signed-off-by: Tobias Schramm <tobleminer@gmail.com> Signed-off-by: Greg Kurz <groug@kaod.org>
This commit is contained in:
parent
790db7efdb
commit
b96feb2cb9
|
@ -76,6 +76,8 @@ typedef struct FsDriverEntry {
|
||||||
int export_flags;
|
int export_flags;
|
||||||
FileOperations *ops;
|
FileOperations *ops;
|
||||||
FsThrottle fst;
|
FsThrottle fst;
|
||||||
|
mode_t fmode;
|
||||||
|
mode_t dmode;
|
||||||
} FsDriverEntry;
|
} FsDriverEntry;
|
||||||
|
|
||||||
typedef struct FsContext
|
typedef struct FsContext
|
||||||
|
@ -88,6 +90,8 @@ typedef struct FsContext
|
||||||
FsThrottle *fst;
|
FsThrottle *fst;
|
||||||
/* fs driver specific data */
|
/* fs driver specific data */
|
||||||
void *private;
|
void *private;
|
||||||
|
mode_t fmode;
|
||||||
|
mode_t dmode;
|
||||||
} FsContext;
|
} FsContext;
|
||||||
|
|
||||||
typedef struct V9fsPath {
|
typedef struct V9fsPath {
|
||||||
|
|
|
@ -38,6 +38,12 @@ static QemuOptsList qemu_fsdev_opts = {
|
||||||
}, {
|
}, {
|
||||||
.name = "sock_fd",
|
.name = "sock_fd",
|
||||||
.type = QEMU_OPT_NUMBER,
|
.type = QEMU_OPT_NUMBER,
|
||||||
|
}, {
|
||||||
|
.name = "fmode",
|
||||||
|
.type = QEMU_OPT_NUMBER,
|
||||||
|
}, {
|
||||||
|
.name = "dmode",
|
||||||
|
.type = QEMU_OPT_NUMBER,
|
||||||
},
|
},
|
||||||
|
|
||||||
THROTTLE_OPTS,
|
THROTTLE_OPTS,
|
||||||
|
@ -75,6 +81,12 @@ static QemuOptsList qemu_virtfs_opts = {
|
||||||
}, {
|
}, {
|
||||||
.name = "sock_fd",
|
.name = "sock_fd",
|
||||||
.type = QEMU_OPT_NUMBER,
|
.type = QEMU_OPT_NUMBER,
|
||||||
|
}, {
|
||||||
|
.name = "fmode",
|
||||||
|
.type = QEMU_OPT_NUMBER,
|
||||||
|
}, {
|
||||||
|
.name = "dmode",
|
||||||
|
.type = QEMU_OPT_NUMBER,
|
||||||
},
|
},
|
||||||
|
|
||||||
{ /*End of list */ }
|
{ /*End of list */ }
|
||||||
|
|
|
@ -633,7 +633,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
|
||||||
|
|
||||||
if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
|
if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
|
||||||
fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
||||||
err = mknodat(dirfd, name, SM_LOCAL_MODE_BITS | S_IFREG, 0);
|
err = mknodat(dirfd, name, fs_ctx->fmode | S_IFREG, 0);
|
||||||
if (err == -1) {
|
if (err == -1) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -685,7 +685,7 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
|
||||||
|
|
||||||
if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
|
if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
|
||||||
fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
||||||
err = mkdirat(dirfd, name, SM_LOCAL_DIR_MODE_BITS);
|
err = mkdirat(dirfd, name, fs_ctx->dmode);
|
||||||
if (err == -1) {
|
if (err == -1) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -786,7 +786,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
|
||||||
/* Determine the security model */
|
/* Determine the security model */
|
||||||
if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
|
if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
|
||||||
fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
|
||||||
fd = openat_file(dirfd, name, flags, SM_LOCAL_MODE_BITS);
|
fd = openat_file(dirfd, name, flags, fs_ctx->fmode);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -849,7 +849,7 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
|
||||||
ssize_t oldpath_size, write_size;
|
ssize_t oldpath_size, write_size;
|
||||||
|
|
||||||
fd = openat_file(dirfd, name, O_CREAT | O_EXCL | O_RDWR,
|
fd = openat_file(dirfd, name, O_CREAT | O_EXCL | O_RDWR,
|
||||||
SM_LOCAL_MODE_BITS);
|
fs_ctx->fmode);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1467,6 +1467,23 @@ static int local_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fse->export_flags & V9FS_SM_MAPPED ||
|
||||||
|
fse->export_flags & V9FS_SM_MAPPED_FILE) {
|
||||||
|
fse->fmode =
|
||||||
|
qemu_opt_get_number(opts, "fmode", SM_LOCAL_MODE_BITS) & 0777;
|
||||||
|
fse->dmode =
|
||||||
|
qemu_opt_get_number(opts, "dmode", SM_LOCAL_DIR_MODE_BITS) & 0777;
|
||||||
|
} else {
|
||||||
|
if (qemu_opt_find(opts, "fmode")) {
|
||||||
|
error_report("fmode is only valid for mapped 9p modes");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (qemu_opt_find(opts, "dmode")) {
|
||||||
|
error_report("dmode is only valid for mapped 9p modes");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fse->path = g_strdup(path);
|
fse->path = g_strdup(path);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -3533,6 +3533,9 @@ int v9fs_device_realize_common(V9fsState *s, Error **errp)
|
||||||
|
|
||||||
s->ops = fse->ops;
|
s->ops = fse->ops;
|
||||||
|
|
||||||
|
s->ctx.fmode = fse->fmode;
|
||||||
|
s->ctx.dmode = fse->dmode;
|
||||||
|
|
||||||
s->fid_list = NULL;
|
s->fid_list = NULL;
|
||||||
qemu_co_rwlock_init(&s->rename_lock);
|
qemu_co_rwlock_init(&s->rename_lock);
|
||||||
|
|
||||||
|
|
|
@ -1010,7 +1010,7 @@ ETEXI
|
||||||
|
|
||||||
DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
|
DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
|
||||||
"-fsdev fsdriver,id=id[,path=path,][security_model={mapped-xattr|mapped-file|passthrough|none}]\n"
|
"-fsdev fsdriver,id=id[,path=path,][security_model={mapped-xattr|mapped-file|passthrough|none}]\n"
|
||||||
" [,writeout=immediate][,readonly][,socket=socket|sock_fd=sock_fd]\n"
|
" [,writeout=immediate][,readonly][,socket=socket|sock_fd=sock_fd][,fmode=fmode][,dmode=dmode]\n"
|
||||||
" [[,throttling.bps-total=b]|[[,throttling.bps-read=r][,throttling.bps-write=w]]]\n"
|
" [[,throttling.bps-total=b]|[[,throttling.bps-read=r][,throttling.bps-write=w]]]\n"
|
||||||
" [[,throttling.iops-total=i]|[[,throttling.iops-read=r][,throttling.iops-write=w]]]\n"
|
" [[,throttling.iops-total=i]|[[,throttling.iops-read=r][,throttling.iops-write=w]]]\n"
|
||||||
" [[,throttling.bps-total-max=bm]|[[,throttling.bps-read-max=rm][,throttling.bps-write-max=wm]]]\n"
|
" [[,throttling.bps-total-max=bm]|[[,throttling.bps-read-max=rm][,throttling.bps-write-max=wm]]]\n"
|
||||||
|
@ -1020,7 +1020,7 @@ DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
|
|
||||||
@item -fsdev @var{fsdriver},id=@var{id},path=@var{path},[security_model=@var{security_model}][,writeout=@var{writeout}][,readonly][,socket=@var{socket}|sock_fd=@var{sock_fd}]
|
@item -fsdev @var{fsdriver},id=@var{id},path=@var{path},[security_model=@var{security_model}][,writeout=@var{writeout}][,readonly][,socket=@var{socket}|sock_fd=@var{sock_fd}][,fmode=@var{fmode}][,dmode=@var{dmode}]
|
||||||
@findex -fsdev
|
@findex -fsdev
|
||||||
Define a new file system device. Valid options are:
|
Define a new file system device. Valid options are:
|
||||||
@table @option
|
@table @option
|
||||||
|
@ -1061,6 +1061,12 @@ with virtfs-proxy-helper
|
||||||
Enables proxy filesystem driver to use passed socket descriptor for
|
Enables proxy filesystem driver to use passed socket descriptor for
|
||||||
communicating with virtfs-proxy-helper. Usually a helper like libvirt
|
communicating with virtfs-proxy-helper. Usually a helper like libvirt
|
||||||
will create socketpair and pass one of the fds as sock_fd
|
will create socketpair and pass one of the fds as sock_fd
|
||||||
|
@item fmode=@var{fmode}
|
||||||
|
Specifies the default mode for newly created files on the host. Works only
|
||||||
|
with security models "mapped-xattr" and "mapped-file".
|
||||||
|
@item dmode=@var{dmode}
|
||||||
|
Specifies the default mode for newly created directories on the host. Works
|
||||||
|
only with security models "mapped-xattr" and "mapped-file".
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
-fsdev option is used along with -device driver "virtio-9p-pci".
|
-fsdev option is used along with -device driver "virtio-9p-pci".
|
||||||
|
@ -1077,12 +1083,12 @@ ETEXI
|
||||||
|
|
||||||
DEF("virtfs", HAS_ARG, QEMU_OPTION_virtfs,
|
DEF("virtfs", HAS_ARG, QEMU_OPTION_virtfs,
|
||||||
"-virtfs local,path=path,mount_tag=tag,security_model=[mapped-xattr|mapped-file|passthrough|none]\n"
|
"-virtfs local,path=path,mount_tag=tag,security_model=[mapped-xattr|mapped-file|passthrough|none]\n"
|
||||||
" [,id=id][,writeout=immediate][,readonly][,socket=socket|sock_fd=sock_fd]\n",
|
" [,id=id][,writeout=immediate][,readonly][,socket=socket|sock_fd=sock_fd][,fmode=fmode][,dmode=dmode]\n",
|
||||||
QEMU_ARCH_ALL)
|
QEMU_ARCH_ALL)
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
|
|
||||||
@item -virtfs @var{fsdriver}[,path=@var{path}],mount_tag=@var{mount_tag}[,security_model=@var{security_model}][,writeout=@var{writeout}][,readonly][,socket=@var{socket}|sock_fd=@var{sock_fd}]
|
@item -virtfs @var{fsdriver}[,path=@var{path}],mount_tag=@var{mount_tag}[,security_model=@var{security_model}][,writeout=@var{writeout}][,readonly][,socket=@var{socket}|sock_fd=@var{sock_fd}][,fmode=@var{fmode}][,dmode=@var{dmode}]
|
||||||
@findex -virtfs
|
@findex -virtfs
|
||||||
|
|
||||||
The general form of a Virtual File system pass-through options are:
|
The general form of a Virtual File system pass-through options are:
|
||||||
|
@ -1124,6 +1130,12 @@ will create socketpair and pass one of the fds as sock_fd
|
||||||
@item sock_fd
|
@item sock_fd
|
||||||
Enables proxy filesystem driver to use passed 'sock_fd' as the socket
|
Enables proxy filesystem driver to use passed 'sock_fd' as the socket
|
||||||
descriptor for interfacing with virtfs-proxy-helper
|
descriptor for interfacing with virtfs-proxy-helper
|
||||||
|
@item fmode=@var{fmode}
|
||||||
|
Specifies the default mode for newly created files on the host. Works only
|
||||||
|
with security models "mapped-xattr" and "mapped-file".
|
||||||
|
@item dmode=@var{dmode}
|
||||||
|
Specifies the default mode for newly created directories on the host. Works
|
||||||
|
only with security models "mapped-xattr" and "mapped-file".
|
||||||
@end table
|
@end table
|
||||||
ETEXI
|
ETEXI
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue