Browse Source
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>remotes/github/stable-0.14
committed by
Anthony Liguori
7 changed files with 345 additions and 92 deletions
@ -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, |
|||
}; |
|||
@ -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, |
|||
}; |
|||
@ -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 |
|||
Loading…
Reference in new issue