mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-16 01:03:31 +00:00
virtio-9p: Use layered xattr approach
We would need this to make sure we handle the mapped security model correctly for different xattr names. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
This commit is contained in:
parent
0f8151cb75
commit
fc22118d9b
|
@ -249,7 +249,8 @@ sound-obj-$(CONFIG_CS4231A) += cs4231a.o
|
||||||
adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
|
adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
|
||||||
hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
|
hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
|
||||||
|
|
||||||
hw-obj-$(CONFIG_VIRTFS) += virtio-9p-debug.o virtio-9p-local.o
|
hw-obj-$(CONFIG_VIRTFS) += virtio-9p-debug.o virtio-9p-local.o virtio-9p-xattr.o
|
||||||
|
hw-obj-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# libdis
|
# libdis
|
||||||
|
|
|
@ -47,11 +47,14 @@ typedef struct FsCred
|
||||||
dev_t fc_rdev;
|
dev_t fc_rdev;
|
||||||
} FsCred;
|
} FsCred;
|
||||||
|
|
||||||
|
struct xattr_operations;
|
||||||
|
|
||||||
typedef struct FsContext
|
typedef struct FsContext
|
||||||
{
|
{
|
||||||
char *fs_root;
|
char *fs_root;
|
||||||
SecModel fs_sm;
|
SecModel fs_sm;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
|
struct xattr_operations **xops;
|
||||||
} FsContext;
|
} FsContext;
|
||||||
|
|
||||||
extern void cred_init(FsCred *);
|
extern void cred_init(FsCred *);
|
||||||
|
@ -94,4 +97,12 @@ typedef struct FileOperations
|
||||||
int (*lremovexattr)(FsContext *, const char *, const char *);
|
int (*lremovexattr)(FsContext *, const char *, const char *);
|
||||||
void *opaque;
|
void *opaque;
|
||||||
} FileOperations;
|
} FileOperations;
|
||||||
|
|
||||||
|
static inline const char *rpath(FsContext *ctx, const char *path)
|
||||||
|
{
|
||||||
|
/* FIXME: so wrong... */
|
||||||
|
static char buffer[4096];
|
||||||
|
snprintf(buffer, sizeof(buffer), "%s/%s", ctx->fs_root, path);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
*/
|
*/
|
||||||
#include "virtio.h"
|
#include "virtio.h"
|
||||||
#include "virtio-9p.h"
|
#include "virtio-9p.h"
|
||||||
|
#include "virtio-9p-xattr.h"
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
@ -19,14 +20,6 @@
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <attr/xattr.h>
|
#include <attr/xattr.h>
|
||||||
|
|
||||||
static const char *rpath(FsContext *ctx, const char *path)
|
|
||||||
{
|
|
||||||
/* FIXME: so wrong... */
|
|
||||||
static char buffer[4096];
|
|
||||||
snprintf(buffer, sizeof(buffer), "%s/%s", ctx->fs_root, path);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
|
static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
|
||||||
{
|
{
|
||||||
|
@ -497,103 +490,25 @@ static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf)
|
||||||
static ssize_t local_lgetxattr(FsContext *ctx, const char *path,
|
static ssize_t local_lgetxattr(FsContext *ctx, const char *path,
|
||||||
const char *name, void *value, size_t size)
|
const char *name, void *value, size_t size)
|
||||||
{
|
{
|
||||||
if ((ctx->fs_sm == SM_MAPPED) &&
|
return v9fs_get_xattr(ctx, path, name, value, size);
|
||||||
(strncmp(name, "user.virtfs.", 12) == 0)) {
|
|
||||||
/*
|
|
||||||
* Don't allow fetch of user.virtfs namesapce
|
|
||||||
* in case of mapped security
|
|
||||||
*/
|
|
||||||
errno = ENOATTR;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return lgetxattr(rpath(ctx, path), name, value, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t local_llistxattr(FsContext *ctx, const char *path,
|
static ssize_t local_llistxattr(FsContext *ctx, const char *path,
|
||||||
void *value, size_t size)
|
void *value, size_t size)
|
||||||
{
|
{
|
||||||
ssize_t retval;
|
return v9fs_list_xattr(ctx, path, value, size);
|
||||||
ssize_t actual_len = 0;
|
|
||||||
char *orig_value, *orig_value_start;
|
|
||||||
char *temp_value, *temp_value_start;
|
|
||||||
ssize_t xattr_len, parsed_len = 0, attr_len;
|
|
||||||
|
|
||||||
if (ctx->fs_sm != SM_MAPPED) {
|
|
||||||
return llistxattr(rpath(ctx, path), value, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the actual len */
|
|
||||||
xattr_len = llistxattr(rpath(ctx, path), value, 0);
|
|
||||||
|
|
||||||
/* Now fetch the xattr and find the actual size */
|
|
||||||
orig_value = qemu_malloc(xattr_len);
|
|
||||||
xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For mapped security model drop user.virtfs namespace
|
|
||||||
* from the list
|
|
||||||
*/
|
|
||||||
temp_value = qemu_mallocz(xattr_len);
|
|
||||||
temp_value_start = temp_value;
|
|
||||||
orig_value_start = orig_value;
|
|
||||||
while (xattr_len > parsed_len) {
|
|
||||||
attr_len = strlen(orig_value) + 1;
|
|
||||||
if (strncmp(orig_value, "user.virtfs.", 12) != 0) {
|
|
||||||
/* Copy this entry */
|
|
||||||
strcat(temp_value, orig_value);
|
|
||||||
temp_value += attr_len;
|
|
||||||
actual_len += attr_len;
|
|
||||||
}
|
|
||||||
parsed_len += attr_len;
|
|
||||||
orig_value += attr_len;
|
|
||||||
}
|
|
||||||
if (!size) {
|
|
||||||
retval = actual_len;
|
|
||||||
goto out;
|
|
||||||
} else if (size >= actual_len) {
|
|
||||||
/* now copy the parsed attribute list back */
|
|
||||||
memset(value, 0, size);
|
|
||||||
memcpy(value, temp_value_start, actual_len);
|
|
||||||
retval = actual_len;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
errno = ERANGE;
|
|
||||||
retval = -1;
|
|
||||||
out:
|
|
||||||
qemu_free(orig_value_start);
|
|
||||||
qemu_free(temp_value_start);
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int local_lsetxattr(FsContext *ctx, const char *path, const char *name,
|
static int local_lsetxattr(FsContext *ctx, const char *path, const char *name,
|
||||||
void *value, size_t size, int flags)
|
void *value, size_t size, int flags)
|
||||||
{
|
{
|
||||||
if ((ctx->fs_sm == SM_MAPPED) &&
|
return v9fs_set_xattr(ctx, path, name, value, size, flags);
|
||||||
(strncmp(name, "user.virtfs.", 12) == 0)) {
|
|
||||||
/*
|
|
||||||
* Don't allow fetch of user.virtfs namesapce
|
|
||||||
* in case of mapped security
|
|
||||||
*/
|
|
||||||
errno = EACCES;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return lsetxattr(rpath(ctx, path), name, value, size, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int local_lremovexattr(FsContext *ctx,
|
static int local_lremovexattr(FsContext *ctx,
|
||||||
const char *path, const char *name)
|
const char *path, const char *name)
|
||||||
{
|
{
|
||||||
if ((ctx->fs_sm == SM_MAPPED) &&
|
return v9fs_remove_xattr(ctx, path, name);
|
||||||
(strncmp(name, "user.virtfs.", 12) == 0)) {
|
|
||||||
/*
|
|
||||||
* Don't allow fetch of user.virtfs namesapce
|
|
||||||
* in case of mapped security
|
|
||||||
*/
|
|
||||||
errno = EACCES;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return lremovexattr(rpath(ctx, path), name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
101
hw/virtio-9p-xattr-user.c
Normal file
101
hw/virtio-9p-xattr-user.c
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* Virtio 9p user. xattr callback
|
||||||
|
*
|
||||||
|
* Copyright IBM, Corp. 2010
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
|
||||||
|
*
|
||||||
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||||
|
* the COPYING file in the top-level directory.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include "virtio.h"
|
||||||
|
#include "virtio-9p.h"
|
||||||
|
#include "file-op-9p.h"
|
||||||
|
#include "virtio-9p-xattr.h"
|
||||||
|
|
||||||
|
|
||||||
|
static ssize_t mp_user_getxattr(FsContext *ctx, const char *path,
|
||||||
|
const char *name, void *value, size_t size)
|
||||||
|
{
|
||||||
|
if (strncmp(name, "user.virtfs.", 12) == 0) {
|
||||||
|
/*
|
||||||
|
* Don't allow fetch of user.virtfs namesapce
|
||||||
|
* in case of mapped security
|
||||||
|
*/
|
||||||
|
errno = ENOATTR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return lgetxattr(rpath(ctx, path), name, value, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t mp_user_listxattr(FsContext *ctx, const char *path,
|
||||||
|
char *name, void *value, size_t size)
|
||||||
|
{
|
||||||
|
int name_size = strlen(name) + 1;
|
||||||
|
if (strncmp(name, "user.virtfs.", 12) == 0) {
|
||||||
|
/*
|
||||||
|
* Don't allow fetch of user.virtfs namesapce
|
||||||
|
* in case of mapped security
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!value) {
|
||||||
|
return name_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < name_size) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(value, name, name_size);
|
||||||
|
return name_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name,
|
||||||
|
void *value, size_t size, int flags)
|
||||||
|
{
|
||||||
|
if (strncmp(name, "user.virtfs.", 12) == 0) {
|
||||||
|
/*
|
||||||
|
* Don't allow fetch of user.virtfs namesapce
|
||||||
|
* in case of mapped security
|
||||||
|
*/
|
||||||
|
errno = EACCES;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return lsetxattr(rpath(ctx, path), name, value, size, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mp_user_removexattr(FsContext *ctx,
|
||||||
|
const char *path, const char *name)
|
||||||
|
{
|
||||||
|
if (strncmp(name, "user.virtfs.", 12) == 0) {
|
||||||
|
/*
|
||||||
|
* Don't allow fetch of user.virtfs namesapce
|
||||||
|
* in case of mapped security
|
||||||
|
*/
|
||||||
|
errno = EACCES;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return lremovexattr(rpath(ctx, path), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
XattrOperations mapped_user_xattr = {
|
||||||
|
.name = "user.",
|
||||||
|
.getxattr = mp_user_getxattr,
|
||||||
|
.setxattr = mp_user_setxattr,
|
||||||
|
.listxattr = mp_user_listxattr,
|
||||||
|
.removexattr = mp_user_removexattr,
|
||||||
|
};
|
||||||
|
|
||||||
|
XattrOperations passthrough_user_xattr = {
|
||||||
|
.name = "user.",
|
||||||
|
.getxattr = pt_getxattr,
|
||||||
|
.setxattr = pt_setxattr,
|
||||||
|
.listxattr = pt_listxattr,
|
||||||
|
.removexattr = pt_removexattr,
|
||||||
|
};
|
152
hw/virtio-9p-xattr.c
Normal file
152
hw/virtio-9p-xattr.c
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
* Virtio 9p xattr callback
|
||||||
|
*
|
||||||
|
* Copyright IBM, Corp. 2010
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
|
||||||
|
*
|
||||||
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||||
|
* the COPYING file in the top-level directory.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "virtio.h"
|
||||||
|
#include "virtio-9p.h"
|
||||||
|
#include "file-op-9p.h"
|
||||||
|
#include "virtio-9p-xattr.h"
|
||||||
|
|
||||||
|
|
||||||
|
static XattrOperations *get_xattr_operations(XattrOperations **h,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
XattrOperations *xops;
|
||||||
|
for (xops = *(h)++; xops != NULL; xops = *(h)++) {
|
||||||
|
if (!strncmp(name, xops->name, strlen(xops->name))) {
|
||||||
|
return xops;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t v9fs_get_xattr(FsContext *ctx, const char *path,
|
||||||
|
const char *name, void *value, size_t size)
|
||||||
|
{
|
||||||
|
XattrOperations *xops = get_xattr_operations(ctx->xops, name);
|
||||||
|
if (xops) {
|
||||||
|
return xops->getxattr(ctx, path, name, value, size);
|
||||||
|
}
|
||||||
|
errno = -EOPNOTSUPP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t pt_listxattr(FsContext *ctx, const char *path,
|
||||||
|
char *name, void *value, size_t size)
|
||||||
|
{
|
||||||
|
int name_size = strlen(name) + 1;
|
||||||
|
if (!value) {
|
||||||
|
return name_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < name_size) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(value, name, name_size);
|
||||||
|
return name_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the list and pass to each layer to find out whether
|
||||||
|
* to send the data or not
|
||||||
|
*/
|
||||||
|
ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
|
||||||
|
void *value, size_t vsize)
|
||||||
|
{
|
||||||
|
ssize_t size = 0;
|
||||||
|
void *ovalue = value;
|
||||||
|
XattrOperations *xops;
|
||||||
|
char *orig_value, *orig_value_start;
|
||||||
|
ssize_t xattr_len, parsed_len = 0, attr_len;
|
||||||
|
|
||||||
|
/* Get the actual len */
|
||||||
|
xattr_len = llistxattr(rpath(ctx, path), value, 0);
|
||||||
|
|
||||||
|
/* Now fetch the xattr and find the actual size */
|
||||||
|
orig_value = qemu_malloc(xattr_len);
|
||||||
|
xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len);
|
||||||
|
|
||||||
|
/* store the orig pointer */
|
||||||
|
orig_value_start = orig_value;
|
||||||
|
while (xattr_len > parsed_len) {
|
||||||
|
xops = get_xattr_operations(ctx->xops, orig_value);
|
||||||
|
if (!xops) {
|
||||||
|
goto next_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
size += xops->listxattr(ctx, path, orig_value, value, vsize);
|
||||||
|
} else {
|
||||||
|
size = xops->listxattr(ctx, path, orig_value, value, vsize);
|
||||||
|
if (size < 0) {
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
value += size;
|
||||||
|
vsize -= size;
|
||||||
|
}
|
||||||
|
next_entry:
|
||||||
|
/* Got the next entry */
|
||||||
|
attr_len = strlen(orig_value) + 1;
|
||||||
|
parsed_len += attr_len;
|
||||||
|
orig_value += attr_len;
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
size = value - ovalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
qemu_free(orig_value_start);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name,
|
||||||
|
void *value, size_t size, int flags)
|
||||||
|
{
|
||||||
|
XattrOperations *xops = get_xattr_operations(ctx->xops, name);
|
||||||
|
if (xops) {
|
||||||
|
return xops->setxattr(ctx, path, name, value, size, flags);
|
||||||
|
}
|
||||||
|
errno = -EOPNOTSUPP;
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int v9fs_remove_xattr(FsContext *ctx,
|
||||||
|
const char *path, const char *name)
|
||||||
|
{
|
||||||
|
XattrOperations *xops = get_xattr_operations(ctx->xops, name);
|
||||||
|
if (xops) {
|
||||||
|
return xops->removexattr(ctx, path, name);
|
||||||
|
}
|
||||||
|
errno = -EOPNOTSUPP;
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
XattrOperations *mapped_xattr_ops[] = {
|
||||||
|
&mapped_user_xattr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
XattrOperations *passthrough_xattr_ops[] = {
|
||||||
|
&passthrough_user_xattr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* for .user none model should be same as passthrough */
|
||||||
|
XattrOperations *none_xattr_ops[] = {
|
||||||
|
&passthrough_user_xattr,
|
||||||
|
NULL,
|
||||||
|
};
|
69
hw/virtio-9p-xattr.h
Normal file
69
hw/virtio-9p-xattr.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Virtio 9p
|
||||||
|
*
|
||||||
|
* Copyright IBM, Corp. 2010
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
|
||||||
|
*
|
||||||
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||||
|
* the COPYING file in the top-level directory.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef _QEMU_VIRTIO_9P_XATTR_H
|
||||||
|
#define _QEMU_VIRTIO_9P_XATTR_H
|
||||||
|
|
||||||
|
#include <attr/xattr.h>
|
||||||
|
|
||||||
|
typedef struct xattr_operations
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
ssize_t (*getxattr)(FsContext *ctx, const char *path,
|
||||||
|
const char *name, void *value, size_t size);
|
||||||
|
ssize_t (*listxattr)(FsContext *ctx, const char *path,
|
||||||
|
char *name, void *value, size_t size);
|
||||||
|
int (*setxattr)(FsContext *ctx, const char *path, const char *name,
|
||||||
|
void *value, size_t size, int flags);
|
||||||
|
int (*removexattr)(FsContext *ctx,
|
||||||
|
const char *path, const char *name);
|
||||||
|
} XattrOperations;
|
||||||
|
|
||||||
|
|
||||||
|
extern XattrOperations mapped_user_xattr;
|
||||||
|
extern XattrOperations passthrough_user_xattr;
|
||||||
|
|
||||||
|
extern XattrOperations *mapped_xattr_ops[];
|
||||||
|
extern XattrOperations *passthrough_xattr_ops[];
|
||||||
|
extern XattrOperations *none_xattr_ops[];
|
||||||
|
|
||||||
|
extern ssize_t v9fs_get_xattr(FsContext *ctx, const char *path,
|
||||||
|
const char *name, void *value, size_t size);
|
||||||
|
extern ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
|
||||||
|
void *value, size_t vsize);
|
||||||
|
extern int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name,
|
||||||
|
void *value, size_t size, int flags);
|
||||||
|
extern int v9fs_remove_xattr(FsContext *ctx,
|
||||||
|
const char *path, const char *name);
|
||||||
|
extern ssize_t pt_listxattr(FsContext *ctx, const char *path,
|
||||||
|
char *name, void *value, size_t size);
|
||||||
|
|
||||||
|
static inline ssize_t pt_getxattr(FsContext *ctx, const char *path,
|
||||||
|
const char *name, void *value, size_t size)
|
||||||
|
{
|
||||||
|
return lgetxattr(rpath(ctx, path), name, value, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int pt_setxattr(FsContext *ctx, const char *path,
|
||||||
|
const char *name, void *value,
|
||||||
|
size_t size, int flags)
|
||||||
|
{
|
||||||
|
return lsetxattr(rpath(ctx, path), name, value, size, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int pt_removexattr(FsContext *ctx,
|
||||||
|
const char *path, const char *name)
|
||||||
|
{
|
||||||
|
return lremovexattr(rpath(ctx, path), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -17,6 +17,7 @@
|
||||||
#include "virtio-9p.h"
|
#include "virtio-9p.h"
|
||||||
#include "fsdev/qemu-fsdev.h"
|
#include "fsdev/qemu-fsdev.h"
|
||||||
#include "virtio-9p-debug.h"
|
#include "virtio-9p-debug.h"
|
||||||
|
#include "virtio-9p-xattr.h"
|
||||||
|
|
||||||
int debug_9p_pdu;
|
int debug_9p_pdu;
|
||||||
|
|
||||||
|
@ -3712,23 +3713,26 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
|
||||||
if (!strcmp(fse->security_model, "passthrough")) {
|
if (!strcmp(fse->security_model, "passthrough")) {
|
||||||
/* Files on the Fileserver set to client user credentials */
|
/* Files on the Fileserver set to client user credentials */
|
||||||
s->ctx.fs_sm = SM_PASSTHROUGH;
|
s->ctx.fs_sm = SM_PASSTHROUGH;
|
||||||
|
s->ctx.xops = passthrough_xattr_ops;
|
||||||
} else if (!strcmp(fse->security_model, "mapped")) {
|
} else if (!strcmp(fse->security_model, "mapped")) {
|
||||||
/* Files on the fileserver are set to QEMU credentials.
|
/* Files on the fileserver are set to QEMU credentials.
|
||||||
* Client user credentials are saved in extended attributes.
|
* Client user credentials are saved in extended attributes.
|
||||||
*/
|
*/
|
||||||
s->ctx.fs_sm = SM_MAPPED;
|
s->ctx.fs_sm = SM_MAPPED;
|
||||||
|
s->ctx.xops = mapped_xattr_ops;
|
||||||
} else if (!strcmp(fse->security_model, "none")) {
|
} else if (!strcmp(fse->security_model, "none")) {
|
||||||
/*
|
/*
|
||||||
* Files on the fileserver are set to QEMU credentials.
|
* Files on the fileserver are set to QEMU credentials.
|
||||||
*/
|
*/
|
||||||
s->ctx.fs_sm = SM_NONE;
|
s->ctx.fs_sm = SM_NONE;
|
||||||
|
s->ctx.xops = none_xattr_ops;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Default to security_model=none. You may want"
|
fprintf(stderr, "Default to security_model=none. You may want"
|
||||||
" enable advanced security model using "
|
" enable advanced security model using "
|
||||||
"security option:\n\t security_model=passthrough \n\t "
|
"security option:\n\t security_model=passthrough \n\t "
|
||||||
"security_model=mapped\n");
|
"security_model=mapped\n");
|
||||||
s->ctx.fs_sm = SM_NONE;
|
s->ctx.fs_sm = SM_NONE;
|
||||||
|
s->ctx.xops = none_xattr_ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lstat(fse->path, &stat)) {
|
if (lstat(fse->path, &stat)) {
|
||||||
|
|
Loading…
Reference in a new issue