* [Qemu-devel] [PATCH 1/6] virtio-9p: Introduces an option to specify the security model.
2010-05-10 20:23 [Qemu-devel] [PATCH 0/6] virtio-9p:Introducing security model for VirtFS Venkateswararao Jujjuri (JV)
@ 2010-05-10 20:23 ` Venkateswararao Jujjuri (JV)
2010-05-10 20:24 ` [Qemu-devel] [PATCH 2/6] virtio-9p: Rearrange fileop structures Venkateswararao Jujjuri (JV)
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Venkateswararao Jujjuri (JV) @ 2010-05-10 20:23 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, Venkateswararao Jujjuri (JV)
The new option is:
-fsdev local,id=jvrao,path=/tmp/,security_model=[mapped|passthrough]
-virtfs local,path=/tmp/,security_model=[mapped|passthrough],mnt_tag=v_tmp.
In the case of mapped security model, files are created with QEMU user
credentials and the client-user's credentials are saved in extended attributes.
Whereas in the case of passthrough security model, files on the
filesystem are directly created with client-user's credentials.
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
fsdev/qemu-fsdev.c | 2 ++
fsdev/qemu-fsdev.h | 1 +
hw/virtio-9p.c | 14 ++++++++++++++
qemu-config.c | 12 +++++++++---
qemu-options.hx | 15 +++++++++++----
vl.c | 8 +++++---
6 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
index 813e1f7..8148518 100644
--- a/fsdev/qemu-fsdev.c
+++ b/fsdev/qemu-fsdev.c
@@ -50,6 +50,8 @@ int qemu_fsdev_add(QemuOpts *opts)
fsle->fse.fsdev_id = qemu_strdup(qemu_opts_id(opts));
fsle->fse.path = qemu_strdup(qemu_opt_get(opts, "path"));
+ fsle->fse.security_model = qemu_strdup(qemu_opt_get(opts,
+ "security_model"));
fsle->fse.ops = FsTypes[i].ops;
QTAILQ_INSERT_TAIL(&fstype_entries, fsle, next);
diff --git a/fsdev/qemu-fsdev.h b/fsdev/qemu-fsdev.h
index b50fbe0..6c27881 100644
--- a/fsdev/qemu-fsdev.h
+++ b/fsdev/qemu-fsdev.h
@@ -40,6 +40,7 @@ typedef struct FsTypeTable {
typedef struct FsTypeEntry {
char *fsdev_id;
char *path;
+ char *security_model;
FileOperations *ops;
} FsTypeEntry;
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index e5d0112..62be770 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -2346,6 +2346,20 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
exit(1);
}
+ if (!strcmp(fse->security_model, "passthrough")) {
+ /* Files on the Fileserver set to client user credentials */
+ } else if (!strcmp(fse->security_model, "mapped")) {
+ /* Files on the fileserver are set to QEMU credentials.
+ * Client user credentials are saved in extended attributes.
+ */
+ } else {
+ /* user haven't specified a correct security option */
+ fprintf(stderr, "one of the following must be specified as the"
+ "security option:\n\t security_model=passthrough \n\t "
+ "security_model=mapped\n");
+ exit(1);
+ }
+
if (lstat(fse->path, &stat)) {
fprintf(stderr, "share path %s does not exist\n", fse->path);
exit(1);
diff --git a/qemu-config.c b/qemu-config.c
index d500885..e1e3aa1 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -160,9 +160,12 @@ QemuOptsList qemu_fsdev_opts = {
{
.name = "fstype",
.type = QEMU_OPT_STRING,
- }, {
+ },{
.name = "path",
.type = QEMU_OPT_STRING,
+ },{
+ .name = "security_model",
+ .type = QEMU_OPT_STRING,
},
{ /*End of list */ }
},
@@ -178,12 +181,15 @@ QemuOptsList qemu_virtfs_opts = {
{
.name = "fstype",
.type = QEMU_OPT_STRING,
- }, {
+ },{
.name = "path",
.type = QEMU_OPT_STRING,
- }, {
+ },{
.name = "mount_tag",
.type = QEMU_OPT_STRING,
+ },{
+ .name = "security_model",
+ .type = QEMU_OPT_STRING,
},
{ /*End of list */ }
diff --git a/qemu-options.hx b/qemu-options.hx
index 12f6b51..d557c92 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -482,7 +482,7 @@ ETEXI
DEFHEADING(File system options:)
DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
- "-fsdev local,id=id,path=path\n",
+ "-fsdev local,id=id,path=path,security_model=[mapped|passthrough]\n",
QEMU_ARCH_ALL)
STEXI
@@ -498,7 +498,7 @@ The specific Fstype will determine the applicable options.
Options to each backend are described below.
-@item -fsdev local ,id=@var{id} ,path=@var{path}
+@item -fsdev local ,id=@var{id} ,path=@var{path} ,security_model=@var{security_model}
Create a file-system-"device" for local-filesystem.
@@ -506,6 +506,9 @@ Create a file-system-"device" for local-filesystem.
@option{path} specifies the path to be exported. @option{path} is required.
+@option{security_model} specifies the security model to be followed.
+@option{security_model} is required.
+
@end table
ETEXI
#endif
@@ -514,7 +517,7 @@ ETEXI
DEFHEADING(Virtual File system pass-through options:)
DEF("virtfs", HAS_ARG, QEMU_OPTION_virtfs,
- "-virtfs local,path=path,mount_tag=tag\n",
+ "-virtfs local,path=path,mount_tag=tag,security_model=[mapped|passthrough]\n",
QEMU_ARCH_ALL)
STEXI
@@ -530,7 +533,7 @@ The specific Fstype will determine the applicable options.
Options to each backend are described below.
-@item -virtfs local ,path=@var{path} ,mount_tag=@var{mount_tag}
+@item -virtfs local ,path=@var{path} ,mount_tag=@var{mount_tag} ,security_model=@var{security_model}
Create a Virtual file-system-pass through for local-filesystem.
@@ -538,6 +541,10 @@ Create a Virtual file-system-pass through for local-filesystem.
@option{path} specifies the path to be exported. @option{path} is required.
+@option{security_model} specifies the security model to be followed.
+@option{security_model} is required.
+
+
@option{mount_tag} specifies the tag with which the exported file is mounted.
@option{mount_tag} is required.
diff --git a/vl.c b/vl.c
index 999aac8..3174d91 100644
--- a/vl.c
+++ b/vl.c
@@ -3114,10 +3114,11 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
- len = strlen(",id=,path=");
+ len = strlen(",id=,path=,security_model=");
len += strlen(qemu_opt_get(opts, "fstype"));
len += strlen(qemu_opt_get(opts, "mount_tag"));
len += strlen(qemu_opt_get(opts, "path"));
+ len += strlen(qemu_opt_get(opts, "security_model"));
arg_fsdev = qemu_malloc((len + 1) * sizeof(*arg_fsdev));
if (!arg_fsdev) {
@@ -3126,10 +3127,11 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
- sprintf(arg_fsdev, "%s,id=%s,path=%s",
+ sprintf(arg_fsdev, "%s,id=%s,path=%s,security_model=%s",
qemu_opt_get(opts, "fstype"),
qemu_opt_get(opts, "mount_tag"),
- qemu_opt_get(opts, "path"));
+ qemu_opt_get(opts, "path"),
+ qemu_opt_get(opts, "security_model"));
len = strlen("virtio-9p-pci,fsdev=,mount_tag=");
len += 2*strlen(qemu_opt_get(opts, "mount_tag"));
--
1.6.5.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 2/6] virtio-9p: Rearrange fileop structures
2010-05-10 20:23 [Qemu-devel] [PATCH 0/6] virtio-9p:Introducing security model for VirtFS Venkateswararao Jujjuri (JV)
2010-05-10 20:23 ` [Qemu-devel] [PATCH 1/6] virtio-9p: Introduces an option to specify the security model Venkateswararao Jujjuri (JV)
@ 2010-05-10 20:24 ` Venkateswararao Jujjuri (JV)
2010-05-10 20:24 ` [Qemu-devel] [PATCH 3/6] virtio-9p: modify create/open2 and mkdir for new security model Venkateswararao Jujjuri (JV)
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Venkateswararao Jujjuri (JV) @ 2010-05-10 20:24 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, Venkateswararao Jujjuri (JV)
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
hw/virtio-9p.c | 185 ++++++++++++++------------------------------------------
hw/virtio-9p.h | 92 ++++++++++++++++++++++++++++
2 files changed, 138 insertions(+), 139 deletions(-)
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 62be770..365259c 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -21,6 +21,52 @@
int dotu = 1;
int debug_9p_pdu;
+enum {
+ Oread = 0x00,
+ Owrite = 0x01,
+ Ordwr = 0x02,
+ Oexec = 0x03,
+ Oexcl = 0x04,
+ Otrunc = 0x10,
+ Orexec = 0x20,
+ Orclose = 0x40,
+ Oappend = 0x80,
+};
+
+static int omode_to_uflags(int8_t mode)
+{
+ int ret = 0;
+
+ switch (mode & 3) {
+ case Oread:
+ ret = O_RDONLY;
+ break;
+ case Ordwr:
+ ret = O_RDWR;
+ break;
+ case Owrite:
+ ret = O_WRONLY;
+ break;
+ case Oexec:
+ ret = O_RDONLY;
+ break;
+ }
+
+ if (mode & Otrunc) {
+ ret |= O_TRUNC;
+ }
+
+ if (mode & Oappend) {
+ ret |= O_APPEND;
+ }
+
+ if (mode & Oexcl) {
+ ret |= O_EXCL;
+ }
+
+ return ret;
+}
+
static int v9fs_do_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
{
return s->ops->lstat(&s->ctx, path->data, stbuf);
@@ -995,14 +1041,6 @@ out:
v9fs_string_free(&aname);
}
-typedef struct V9fsStatState {
- V9fsPDU *pdu;
- size_t offset;
- V9fsStat v9stat;
- V9fsFidState *fidp;
- struct stat stbuf;
-} V9fsStatState;
-
static void v9fs_stat_post_lstat(V9fsState *s, V9fsStatState *vs, int err)
{
if (err == -1) {
@@ -1053,19 +1091,6 @@ out:
qemu_free(vs);
}
-typedef struct V9fsWalkState {
- V9fsPDU *pdu;
- size_t offset;
- int16_t nwnames;
- int name_idx;
- V9fsQID *qids;
- V9fsFidState *fidp;
- V9fsFidState *newfidp;
- V9fsString path;
- V9fsString *wnames;
- struct stat stbuf;
-} V9fsWalkState;
-
static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
{
complete_pdu(s, vs->pdu, err);
@@ -1229,62 +1254,6 @@ out:
v9fs_walk_complete(s, vs, err);
}
-typedef struct V9fsOpenState {
- V9fsPDU *pdu;
- size_t offset;
- int8_t mode;
- V9fsFidState *fidp;
- V9fsQID qid;
- struct stat stbuf;
-
-} V9fsOpenState;
-
-enum {
- Oread = 0x00,
- Owrite = 0x01,
- Ordwr = 0x02,
- Oexec = 0x03,
- Oexcl = 0x04,
- Otrunc = 0x10,
- Orexec = 0x20,
- Orclose = 0x40,
- Oappend = 0x80,
-};
-
-static int omode_to_uflags(int8_t mode)
-{
- int ret = 0;
-
- switch (mode & 3) {
- case Oread:
- ret = O_RDONLY;
- break;
- case Ordwr:
- ret = O_RDWR;
- break;
- case Owrite:
- ret = O_WRONLY;
- break;
- case Oexec:
- ret = O_RDONLY;
- break;
- }
-
- if (mode & Otrunc) {
- ret |= O_TRUNC;
- }
-
- if (mode & Oappend) {
- ret |= O_APPEND;
- }
-
- if (mode & Oexcl) {
- ret |= O_EXCL;
- }
-
- return ret;
-}
-
static void v9fs_open_post_opendir(V9fsState *s, V9fsOpenState *vs, int err)
{
if (vs->fidp->dir == NULL) {
@@ -1387,25 +1356,6 @@ out:
complete_pdu(s, pdu, err);
}
-typedef struct V9fsReadState {
- V9fsPDU *pdu;
- size_t offset;
- int32_t count;
- int32_t total;
- int64_t off;
- V9fsFidState *fidp;
- struct iovec iov[128]; /* FIXME: bad, bad, bad */
- struct iovec *sg;
- off_t dir_pos;
- struct dirent *dent;
- struct stat stbuf;
- V9fsString name;
- V9fsStat v9stat;
- int32_t len;
- int32_t cnt;
- int32_t max_count;
-} V9fsReadState;
-
static void v9fs_read_post_readdir(V9fsState *, V9fsReadState *, ssize_t);
static void v9fs_read_post_seekdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
@@ -1593,19 +1543,6 @@ out:
qemu_free(vs);
}
-typedef struct V9fsWriteState {
- V9fsPDU *pdu;
- size_t offset;
- int32_t len;
- int32_t count;
- int32_t total;
- int64_t off;
- V9fsFidState *fidp;
- struct iovec iov[128]; /* FIXME: bad, bad, bad */
- struct iovec *sg;
- int cnt;
-} V9fsWriteState;
-
static void v9fs_write_post_writev(V9fsState *s, V9fsWriteState *vs,
ssize_t err)
{
@@ -1702,19 +1639,6 @@ out:
qemu_free(vs);
}
-typedef struct V9fsCreateState {
- V9fsPDU *pdu;
- size_t offset;
- V9fsFidState *fidp;
- V9fsQID qid;
- int32_t perm;
- int8_t mode;
- struct stat stbuf;
- V9fsString name;
- V9fsString extension;
- V9fsString fullname;
-} V9fsCreateState;
-
static void v9fs_post_create(V9fsState *s, V9fsCreateState *vs, int err)
{
if (err == 0) {
@@ -1934,12 +1858,6 @@ static void v9fs_flush(V9fsState *s, V9fsPDU *pdu)
complete_pdu(s, pdu, 7);
}
-typedef struct V9fsRemoveState {
- V9fsPDU *pdu;
- size_t offset;
- V9fsFidState *fidp;
-} V9fsRemoveState;
-
static void v9fs_remove_post_remove(V9fsState *s, V9fsRemoveState *vs,
int err)
{
@@ -1982,17 +1900,6 @@ out:
qemu_free(vs);
}
-typedef struct V9fsWstatState
-{
- V9fsPDU *pdu;
- size_t offset;
- int16_t unused;
- V9fsStat v9stat;
- V9fsFidState *fidp;
- struct stat stbuf;
- V9fsString nname;
-} V9fsWstatState;
-
static void v9fs_wstat_post_truncate(V9fsState *s, V9fsWstatState *vs, int err)
{
if (err < 0) {
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index b95dbe4..67f8087 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -146,6 +146,98 @@ typedef struct V9fsState
size_t config_size;
} V9fsState;
+typedef struct V9fsCreateState {
+ V9fsPDU *pdu;
+ size_t offset;
+ V9fsFidState *fidp;
+ V9fsQID qid;
+ int32_t perm;
+ int8_t mode;
+ struct stat stbuf;
+ V9fsString name;
+ V9fsString extension;
+ V9fsString fullname;
+} V9fsCreateState;
+
+typedef struct V9fsStatState {
+ V9fsPDU *pdu;
+ size_t offset;
+ V9fsStat v9stat;
+ V9fsFidState *fidp;
+ struct stat stbuf;
+} V9fsStatState;
+
+typedef struct V9fsWalkState {
+ V9fsPDU *pdu;
+ size_t offset;
+ int16_t nwnames;
+ int name_idx;
+ V9fsQID *qids;
+ V9fsFidState *fidp;
+ V9fsFidState *newfidp;
+ V9fsString path;
+ V9fsString *wnames;
+ struct stat stbuf;
+} V9fsWalkState;
+
+typedef struct V9fsOpenState {
+ V9fsPDU *pdu;
+ size_t offset;
+ int8_t mode;
+ V9fsFidState *fidp;
+ V9fsQID qid;
+ struct stat stbuf;
+} V9fsOpenState;
+
+typedef struct V9fsReadState {
+ V9fsPDU *pdu;
+ size_t offset;
+ int32_t count;
+ int32_t total;
+ int64_t off;
+ V9fsFidState *fidp;
+ struct iovec iov[128]; /* FIXME: bad, bad, bad */
+ struct iovec *sg;
+ off_t dir_pos;
+ struct dirent *dent;
+ struct stat stbuf;
+ V9fsString name;
+ V9fsStat v9stat;
+ int32_t len;
+ int32_t cnt;
+ int32_t max_count;
+} V9fsReadState;
+
+typedef struct V9fsWriteState {
+ V9fsPDU *pdu;
+ size_t offset;
+ int32_t len;
+ int32_t count;
+ int32_t total;
+ int64_t off;
+ V9fsFidState *fidp;
+ struct iovec iov[128]; /* FIXME: bad, bad, bad */
+ struct iovec *sg;
+ int cnt;
+} V9fsWriteState;
+
+typedef struct V9fsRemoveState {
+ V9fsPDU *pdu;
+ size_t offset;
+ V9fsFidState *fidp;
+} V9fsRemoveState;
+
+typedef struct V9fsWstatState
+{
+ V9fsPDU *pdu;
+ size_t offset;
+ int16_t unused;
+ V9fsStat v9stat;
+ V9fsFidState *fidp;
+ struct stat stbuf;
+ V9fsString nname;
+} V9fsWstatState;
+
struct virtio_9p_config
{
/* number of characters in tag */
--
1.6.5.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 3/6] virtio-9p: modify create/open2 and mkdir for new security model.
2010-05-10 20:23 [Qemu-devel] [PATCH 0/6] virtio-9p:Introducing security model for VirtFS Venkateswararao Jujjuri (JV)
2010-05-10 20:23 ` [Qemu-devel] [PATCH 1/6] virtio-9p: Introduces an option to specify the security model Venkateswararao Jujjuri (JV)
2010-05-10 20:24 ` [Qemu-devel] [PATCH 2/6] virtio-9p: Rearrange fileop structures Venkateswararao Jujjuri (JV)
@ 2010-05-10 20:24 ` Venkateswararao Jujjuri (JV)
2010-05-10 20:24 ` [Qemu-devel] [PATCH 4/6] virtio-9p: Implement Security model for mknod related files Venkateswararao Jujjuri (JV)
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Venkateswararao Jujjuri (JV) @ 2010-05-10 20:24 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, Venkateswararao Jujjuri (JV)
Add required infrastructure and modify create/open2 and mkdir per the new
security model.
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
hw/file-op-9p.h | 23 +++++++++-
hw/virtio-9p-local.c | 117 +++++++++++++++++++++++++++++++++----------------
hw/virtio-9p.c | 42 ++++++++++++------
3 files changed, 129 insertions(+), 53 deletions(-)
diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h
index f84767f..1eceeb2 100644
--- a/hw/file-op-9p.h
+++ b/hw/file-op-9p.h
@@ -18,13 +18,32 @@
#include <utime.h>
#include <sys/stat.h>
#include <sys/uio.h>
+#define SM_LOCAL_MODE_BITS 0600
+
+typedef enum
+{
+ sm_none = 0,
+ sm_passthrough, /* uid/gid set on fileserver files */
+ sm_mapped, /* uid/gid part of xattr */
+} SecModel;
+
+typedef struct FsCred
+{
+ uid_t fc_uid;
+ gid_t fc_gid;
+ mode_t fc_mode;
+ dev_t fc_rdev;
+} FsCred;
typedef struct FsContext
{
char *fs_root;
+ SecModel fs_sm;
uid_t uid;
} FsContext;
+extern void cred_init(FsCred *);
+
typedef struct FileOperations
{
int (*lstat)(FsContext *, const char *, struct stat *);
@@ -42,7 +61,7 @@ typedef struct FileOperations
int (*closedir)(FsContext *, DIR *);
DIR *(*opendir)(FsContext *, const char *);
int (*open)(FsContext *, const char *, int);
- int (*open2)(FsContext *, const char *, int, mode_t);
+ int (*open2)(FsContext *, const char *, int, FsCred *);
void (*rewinddir)(FsContext *, DIR *);
off_t (*telldir)(FsContext *, DIR *);
struct dirent *(*readdir)(FsContext *, DIR *);
@@ -50,7 +69,7 @@ typedef struct FileOperations
ssize_t (*readv)(FsContext *, int, const struct iovec *, int);
ssize_t (*writev)(FsContext *, int, const struct iovec *, int);
off_t (*lseek)(FsContext *, int, off_t, int);
- int (*mkdir)(FsContext *, const char *, mode_t);
+ int (*mkdir)(FsContext *, const char *, FsCred *);
int (*fstat)(FsContext *, int, struct stat *);
int (*rename)(FsContext *, const char *, const char *);
int (*truncate)(FsContext *, const char *, off_t);
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index 1afb731..8ed8c66 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -17,6 +17,7 @@
#include <grp.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <attr/xattr.h>
static const char *rpath(FsContext *ctx, const char *path)
{
@@ -31,47 +32,49 @@ static int local_lstat(FsContext *ctx, const char *path, struct stat *stbuf)
return lstat(rpath(ctx, path), stbuf);
}
-static int local_setuid(FsContext *ctx, uid_t uid)
+static void local_set_cred(FsCred *credp)
{
- struct passwd *pw;
- gid_t groups[33];
- int ngroups;
- static uid_t cur_uid = -1;
-
- if (cur_uid == uid) {
- return 0;
+ if (credp->fc_uid != -1) {
+ setuid(credp->fc_uid);
}
-
- if (setreuid(0, 0)) {
- return -1;
+ if (credp->fc_gid != -1) {
+ setgid(credp->fc_gid);
}
+}
- pw = getpwuid(uid);
- if (pw == NULL) {
- return -1;
+static int local_set_xattr(const char *path, FsCred *credp)
+{
+ int err;
+ if (credp->fc_uid != -1) {
+ err = setxattr(path, "user.virtfs.uid", &credp->fc_uid, sizeof(uid_t),
+ XATTR_CREATE);
+ if (err) {
+ return err;
+ }
}
-
- ngroups = 33;
- if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups) == -1) {
- return -1;
+ if (credp->fc_gid != -1) {
+ err = setxattr(path, "user.virtfs.gid", &credp->fc_uid, sizeof(gid_t),
+ XATTR_CREATE);
+ if (err) {
+ return err;
+ }
}
-
- if (setgroups(ngroups, groups)) {
- return -1;
+ if (credp->fc_mode != -1) {
+ err = setxattr(path, "user.virtfs.mode", &credp->fc_mode,
+ sizeof(mode_t), XATTR_CREATE);
+ if (err) {
+ return err;
+ }
}
-
- if (setregid(-1, pw->pw_gid)) {
- return -1;
- }
-
- if (setreuid(-1, uid)) {
- return -1;
+ if (credp->fc_rdev != -1) {
+ err = setxattr(path, "user.virtfs.rdev", &credp->fc_rdev,
+ sizeof(dev_t), XATTR_CREATE);
+ if (err) {
+ return err;
+ }
}
-
- cur_uid = uid;
-
- return 0;
-}
+ return 0;
+ }
static ssize_t local_readlink(FsContext *ctx, const char *path,
char *buf, size_t bufsz)
@@ -168,9 +171,26 @@ static int local_mksock(FsContext *ctx2, const char *path)
return 0;
}
-static int local_mkdir(FsContext *ctx, const char *path, mode_t mode)
+static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp)
{
- return mkdir(rpath(ctx, path), mode);
+ int err = -1;
+ /* Determine the security model */
+ if (fs_ctx->fs_sm == sm_mapped) {
+ err = mkdir(rpath(fs_ctx, path), SM_LOCAL_MODE_BITS);
+ if (err == -1) {
+ return err;
+ }
+ credp->fc_mode = credp->fc_mode|S_IFDIR;
+ err = local_set_xattr(rpath(fs_ctx, path), credp);
+ if (err == -1) {
+ remove(rpath(fs_ctx, path));
+ return err;
+ }
+ } else if (fs_ctx->fs_sm == sm_passthrough) {
+ local_set_cred(credp);
+ err = mkdir(rpath(fs_ctx, path), credp->fc_mode);
+ }
+ return err;
}
static int local_fstat(FsContext *ctx, int fd, struct stat *stbuf)
@@ -178,9 +198,31 @@ static int local_fstat(FsContext *ctx, int fd, struct stat *stbuf)
return fstat(fd, stbuf);
}
-static int local_open2(FsContext *ctx, const char *path, int flags, mode_t mode)
+static int local_open2(FsContext *fs_ctx, const char *path, int flags,
+ FsCred *credp)
{
- return open(rpath(ctx, path), flags, mode);
+ int fd = -1;
+ /* Determine the security model */
+ if (fs_ctx->fs_sm == sm_mapped) {
+ int err;
+ fd = open(rpath(fs_ctx, path), flags, SM_LOCAL_MODE_BITS);
+ if (fd == -1) {
+ goto err_end;
+ }
+ credp->fc_mode = credp->fc_mode|S_IFREG;
+ /* Set cleint credentials in xattr */
+ err = local_set_xattr(rpath(fs_ctx, path), credp);
+ if (err == -1) {
+ close(fd);
+ remove(rpath(fs_ctx, path));
+ return err;
+ }
+ } else if (fs_ctx->fs_sm == sm_passthrough) {
+ local_set_cred(credp);
+ fd = open(rpath(fs_ctx, path), flags, credp->fc_mode);
+ }
+err_end:
+ return fd;
}
static int local_symlink(FsContext *ctx, const char *oldpath,
@@ -264,7 +306,6 @@ static int local_fsync(FsContext *ctx, int fd)
FileOperations local_ops = {
.lstat = local_lstat,
- .setuid = local_setuid,
.readlink = local_readlink,
.close = local_close,
.closedir = local_closedir,
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 365259c..9033541 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -67,14 +67,17 @@ static int omode_to_uflags(int8_t mode)
return ret;
}
-static int v9fs_do_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
+void cred_init(FsCred *credp)
{
- return s->ops->lstat(&s->ctx, path->data, stbuf);
+ credp->fc_uid = -1;
+ credp->fc_gid = -1;
+ credp->fc_mode = -1;
+ credp->fc_rdev = -1;
}
-static int v9fs_do_setuid(V9fsState *s, uid_t uid)
+static int v9fs_do_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
{
- return s->ops->setuid(&s->ctx, uid);
+ return s->ops->lstat(&s->ctx, path->data, stbuf);
}
static ssize_t v9fs_do_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
@@ -164,9 +167,15 @@ static int v9fs_do_mksock(V9fsState *s, V9fsString *path)
return s->ops->mksock(&s->ctx, path->data);
}
-static int v9fs_do_mkdir(V9fsState *s, V9fsString *path, mode_t mode)
+static int v9fs_do_mkdir(V9fsState *s, V9fsCreateState *vs)
{
- return s->ops->mkdir(&s->ctx, path->data, mode);
+ FsCred cred;
+
+ cred_init(&cred);
+ cred.fc_uid = vs->fidp->uid;
+ cred.fc_mode = vs->perm & 0777;
+
+ return s->ops->mkdir(&s->ctx, vs->fullname.data, &cred);
}
static int v9fs_do_fstat(V9fsState *s, int fd, struct stat *stbuf)
@@ -174,9 +183,17 @@ static int v9fs_do_fstat(V9fsState *s, int fd, struct stat *stbuf)
return s->ops->fstat(&s->ctx, fd, stbuf);
}
-static int v9fs_do_open2(V9fsState *s, V9fsString *path, int flags, mode_t mode)
+static int v9fs_do_open2(V9fsState *s, V9fsCreateState *vs)
{
- return s->ops->open2(&s->ctx, path->data, flags, mode);
+ FsCred cred;
+ int flags;
+
+ cred_init(&cred);
+ cred.fc_uid = vs->fidp->uid;
+ cred.fc_mode = vs->perm & 0777;
+ flags = omode_to_uflags(vs->mode) | O_CREAT;
+
+ return s->ops->open2(&s->ctx, vs->fullname.data, flags, &cred);
}
static int v9fs_do_symlink(V9fsState *s, V9fsString *oldpath,
@@ -348,7 +365,6 @@ static V9fsFidState *lookup_fid(V9fsState *s, int32_t fid)
for (f = s->fid_list; f; f = f->next) {
if (f->fid == fid) {
- v9fs_do_setuid(s, f->uid);
return f;
}
}
@@ -1758,7 +1774,7 @@ static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)
}
if (vs->perm & P9_STAT_MODE_DIR) {
- err = v9fs_do_mkdir(s, &vs->fullname, vs->perm & 0777);
+ err = v9fs_do_mkdir(s, vs);
v9fs_create_post_mkdir(s, vs, err);
} else if (vs->perm & P9_STAT_MODE_SYMLINK) {
err = v9fs_do_symlink(s, &vs->extension, &vs->fullname);
@@ -1805,9 +1821,7 @@ static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)
err = v9fs_do_mksock(s, &vs->fullname);
v9fs_create_post_mksock(s, vs, err);
} else {
- vs->fidp->fd = v9fs_do_open2(s, &vs->fullname,
- omode_to_uflags(vs->mode) | O_CREAT,
- vs->perm & 0777);
+ vs->fidp->fd = v9fs_do_open2(s, vs);
v9fs_create_post_open2(s, vs, err);
}
@@ -2255,10 +2269,12 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
if (!strcmp(fse->security_model, "passthrough")) {
/* Files on the Fileserver set to client user credentials */
+ s->ctx.fs_sm = sm_passthrough;
} else if (!strcmp(fse->security_model, "mapped")) {
/* Files on the fileserver are set to QEMU credentials.
* Client user credentials are saved in extended attributes.
*/
+ s->ctx.fs_sm = sm_mapped;
} else {
/* user haven't specified a correct security option */
fprintf(stderr, "one of the following must be specified as the"
--
1.6.5.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 4/6] virtio-9p: Implement Security model for mknod related files
2010-05-10 20:23 [Qemu-devel] [PATCH 0/6] virtio-9p:Introducing security model for VirtFS Venkateswararao Jujjuri (JV)
` (2 preceding siblings ...)
2010-05-10 20:24 ` [Qemu-devel] [PATCH 3/6] virtio-9p: modify create/open2 and mkdir for new security model Venkateswararao Jujjuri (JV)
@ 2010-05-10 20:24 ` Venkateswararao Jujjuri (JV)
2010-05-10 20:24 ` [Qemu-devel] [PATCH 5/6] virtio-9p: Implemented security model for symlink and link Venkateswararao Jujjuri (JV)
2010-05-10 20:24 ` [Qemu-devel] [PATCH 6/6] virtio-9p: Implemented Security model for lstat and fstat Venkateswararao Jujjuri (JV)
5 siblings, 0 replies; 7+ messages in thread
From: Venkateswararao Jujjuri (JV) @ 2010-05-10 20:24 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, Venkateswararao Jujjuri (JV)
In the mapped security model all the special files are created as regular files
on the fileserver and appropriate mode bits are added to the extended
attributes. These extended attributes are used to present this file
as special file to the client.
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
hw/file-op-9p.h | 3 +--
hw/virtio-9p-local.c | 45 +++++++++++++++++++--------------------------
hw/virtio-9p.c | 21 +++++++++++----------
3 files changed, 31 insertions(+), 38 deletions(-)
diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h
index 1eceeb2..f87a35e 100644
--- a/hw/file-op-9p.h
+++ b/hw/file-op-9p.h
@@ -50,8 +50,7 @@ typedef struct FileOperations
ssize_t (*readlink)(FsContext *, const char *, char *, size_t);
int (*chmod)(FsContext *, const char *, mode_t);
int (*chown)(FsContext *, const char *, uid_t, gid_t);
- int (*mknod)(FsContext *, const char *, mode_t, dev_t);
- int (*mksock)(FsContext *, const char *);
+ int (*mknod)(FsContext *, const char *, FsCred *);
int (*utime)(FsContext *, const char *, const struct utimbuf *);
int (*remove)(FsContext *, const char *);
int (*symlink)(FsContext *, const char *, const char *);
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index 8ed8c66..5589f72 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -144,33 +144,27 @@ static int local_chmod(FsContext *ctx, const char *path, mode_t mode)
return chmod(rpath(ctx, path), mode);
}
-static int local_mknod(FsContext *ctx, const char *path, mode_t mode, dev_t dev)
+static int local_mknod(FsContext *fs_ctx, const char *path, FsCred *credp)
{
- return mknod(rpath(ctx, path), mode, dev);
-}
-
-static int local_mksock(FsContext *ctx2, const char *path)
-{
- struct sockaddr_un addr;
- int s;
-
- addr.sun_family = AF_UNIX;
- snprintf(addr.sun_path, 108, "%s", rpath(ctx2, path));
-
- s = socket(PF_UNIX, SOCK_STREAM, 0);
- if (s == -1) {
- return -1;
- }
-
- if (bind(s, (struct sockaddr *)&addr, sizeof(addr))) {
- close(s);
- return -1;
- }
-
- close(s);
- return 0;
+ int err = -1;
+ /* Determine the security model */
+ if (fs_ctx->fs_sm == sm_mapped) {
+ err = mknod(rpath(fs_ctx, path), SM_LOCAL_MODE_BITS|S_IFREG, 0);
+ if (err == -1) {
+ goto err_end;
+ }
+ local_set_xattr(rpath(fs_ctx, path), credp);
+ if (err == -1) {
+ remove(rpath(fs_ctx, path));
+ return err;
+ }
+ } else if (fs_ctx->fs_sm == sm_passthrough) {
+ local_set_cred(credp);
+ err = mknod(rpath(fs_ctx, path), credp->fc_mode, credp->fc_rdev);
+ }
+err_end:
+ return err;
}
-
static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp)
{
int err = -1;
@@ -320,7 +314,6 @@ FileOperations local_ops = {
.writev = local_writev,
.chmod = local_chmod,
.mknod = local_mknod,
- .mksock = local_mksock,
.mkdir = local_mkdir,
.fstat = local_fstat,
.open2 = local_open2,
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 9033541..bbeba7c 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -157,14 +157,15 @@ static int v9fs_do_chmod(V9fsState *s, V9fsString *path, mode_t mode)
return s->ops->chmod(&s->ctx, path->data, mode);
}
-static int v9fs_do_mknod(V9fsState *s, V9fsString *path, mode_t mode, dev_t dev)
+static int v9fs_do_mknod(V9fsState *s, V9fsCreateState *vs, mode_t mode,
+ dev_t dev)
{
- return s->ops->mknod(&s->ctx, path->data, mode, dev);
-}
-
-static int v9fs_do_mksock(V9fsState *s, V9fsString *path)
-{
- return s->ops->mksock(&s->ctx, path->data);
+ FsCred cred;
+ cred_init(&cred);
+ cred.fc_uid = vs->fidp->uid;
+ cred.fc_mode = mode;
+ cred.fc_rdev = dev;
+ return s->ops->mknod(&s->ctx, vs->fullname.data, &cred);
}
static int v9fs_do_mkdir(V9fsState *s, V9fsCreateState *vs)
@@ -1812,13 +1813,13 @@ static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)
}
nmode |= vs->perm & 0777;
- err = v9fs_do_mknod(s, &vs->fullname, nmode, makedev(major, minor));
+ err = v9fs_do_mknod(s, vs, nmode, makedev(major, minor));
v9fs_create_post_perms(s, vs, err);
} else if (vs->perm & P9_STAT_MODE_NAMED_PIPE) {
- err = v9fs_do_mknod(s, &vs->fullname, S_IFIFO | (vs->mode & 0777), 0);
+ err = v9fs_do_mknod(s, vs, S_IFIFO | (vs->perm & 0777), 0);
v9fs_post_create(s, vs, err);
} else if (vs->perm & P9_STAT_MODE_SOCKET) {
- err = v9fs_do_mksock(s, &vs->fullname);
+ err = v9fs_do_mknod(s, vs, S_IFSOCK | (vs->perm & 0777), 0);
v9fs_create_post_mksock(s, vs, err);
} else {
vs->fidp->fd = v9fs_do_open2(s, vs);
--
1.6.5.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 5/6] virtio-9p: Implemented security model for symlink and link.
2010-05-10 20:23 [Qemu-devel] [PATCH 0/6] virtio-9p:Introducing security model for VirtFS Venkateswararao Jujjuri (JV)
` (3 preceding siblings ...)
2010-05-10 20:24 ` [Qemu-devel] [PATCH 4/6] virtio-9p: Implement Security model for mknod related files Venkateswararao Jujjuri (JV)
@ 2010-05-10 20:24 ` Venkateswararao Jujjuri (JV)
2010-05-10 20:24 ` [Qemu-devel] [PATCH 6/6] virtio-9p: Implemented Security model for lstat and fstat Venkateswararao Jujjuri (JV)
5 siblings, 0 replies; 7+ messages in thread
From: Venkateswararao Jujjuri (JV) @ 2010-05-10 20:24 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, Venkateswararao Jujjuri (JV)
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
hw/file-op-9p.h | 4 +-
hw/virtio-9p-local.c | 74 +++++++++++++++++++++++++++++++++++++------------
hw/virtio-9p.c | 24 +++++++++++-----
3 files changed, 75 insertions(+), 27 deletions(-)
diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h
index f87a35e..6ecc009 100644
--- a/hw/file-op-9p.h
+++ b/hw/file-op-9p.h
@@ -53,8 +53,8 @@ typedef struct FileOperations
int (*mknod)(FsContext *, const char *, FsCred *);
int (*utime)(FsContext *, const char *, const struct utimbuf *);
int (*remove)(FsContext *, const char *);
- int (*symlink)(FsContext *, const char *, const char *);
- int (*link)(FsContext *, const char *, const char *);
+ int (*symlink)(FsContext *, const char *, const char *, FsCred *);
+ int (*link)(FsContext *, const char *, const char *, FsCred *);
int (*setuid)(FsContext *, uid_t);
int (*close)(FsContext *, int);
int (*closedir)(FsContext *, DIR *);
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index 5589f72..89b17f0 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -74,12 +74,25 @@ static int local_set_xattr(const char *path, FsCred *credp)
}
}
return 0;
- }
+}
-static ssize_t local_readlink(FsContext *ctx, const char *path,
- char *buf, size_t bufsz)
+static ssize_t local_readlink(FsContext *fs_ctx, const char *path,
+ char *buf, size_t bufsz)
{
- return readlink(rpath(ctx, path), buf, bufsz);
+ ssize_t tsize = -1;
+ if (fs_ctx->fs_sm == sm_mapped) {
+ int fd;
+ fd = open(rpath(fs_ctx, path), O_RDONLY);
+ if (fd == -1) {
+ return -1;
+ }
+ tsize = read(fd, (void *)buf, bufsz);
+ close(fd);
+ return tsize;
+ } else if (fs_ctx->fs_sm == sm_passthrough) {
+ tsize = readlink(rpath(fs_ctx, path), buf, bufsz);
+ }
+ return tsize;
}
static int local_close(FsContext *ctx, int fd)
@@ -219,32 +232,57 @@ err_end:
return fd;
}
-static int local_symlink(FsContext *ctx, const char *oldpath,
- const char *newpath)
+
+static int local_symlink(FsContext *fs_ctx, const char *oldpath,
+ const char *newpath, FsCred *credp)
{
- return symlink(oldpath, rpath(ctx, newpath));
+ int err = -1;
+ /* Determine the security model */
+ if (fs_ctx->fs_sm == sm_mapped) {
+ int fd;
+ ssize_t oldpath_size, write_size;
+ fd = open(rpath(fs_ctx, newpath), O_CREAT|O_EXCL|O_RDWR,
+ SM_LOCAL_MODE_BITS);
+ if (fd == -1) {
+ return -1;
+ }
+ /* Write the oldpath (target) to the file. */
+ oldpath_size = strlen(oldpath) + 1;
+ write_size = write(fd, (void *)oldpath, oldpath_size);
+ if (write_size != oldpath_size) {
+ close(fd);
+ remove(rpath(fs_ctx, newpath));
+ return -1;
+ }
+ close(fd);
+ /* Set cleint credentials in symlink's xattr */
+ credp->fc_mode = credp->fc_mode|S_IFLNK;
+ err = local_set_xattr(rpath(fs_ctx, newpath), credp);
+ if (err == -1) {
+ remove(rpath(fs_ctx, newpath));
+ return err;
+ }
+ } else if (fs_ctx->fs_sm == sm_passthrough) {
+ local_set_cred(credp);
+ err = symlink(oldpath, rpath(fs_ctx, newpath));
+ }
+ return err;
}
-static int local_link(FsContext *ctx, const char *oldpath, const char *newpath)
+static int local_link(FsContext *fs_ctx, const char *oldpath,
+ const char *newpath, FsCred *credp)
{
- char *tmp = qemu_strdup(rpath(ctx, oldpath));
- int err, serrno = 0;
+ char *tmp = qemu_strdup(rpath(fs_ctx, oldpath));
+ int err;
if (tmp == NULL) {
return -ENOMEM;
}
- err = link(tmp, rpath(ctx, newpath));
- if (err == -1) {
- serrno = errno;
- }
+ err = link(tmp, rpath(fs_ctx, newpath));
qemu_free(tmp);
- if (err == -1) {
- errno = serrno;
- }
-
return err;
}
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index bbeba7c..9da14f8 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -197,15 +197,25 @@ static int v9fs_do_open2(V9fsState *s, V9fsCreateState *vs)
return s->ops->open2(&s->ctx, vs->fullname.data, flags, &cred);
}
-static int v9fs_do_symlink(V9fsState *s, V9fsString *oldpath,
- V9fsString *newpath)
+static int v9fs_do_symlink(V9fsState *s, V9fsCreateState *vs)
{
- return s->ops->symlink(&s->ctx, oldpath->data, newpath->data);
+ FsCred cred;
+ cred_init(&cred);
+ cred.fc_uid = vs->fidp->uid;
+ cred.fc_mode = vs->perm | 0777;
+
+ return s->ops->symlink(&s->ctx, vs->extension.data, vs->fullname.data,
+ &cred);
}
-static int v9fs_do_link(V9fsState *s, V9fsString *oldpath, V9fsString *newpath)
+static int v9fs_do_link(V9fsState *s, V9fsFidState *nfidp, V9fsCreateState *vs)
{
- return s->ops->link(&s->ctx, oldpath->data, newpath->data);
+ FsCred cred;
+ cred_init(&cred);
+ cred.fc_uid = nfidp->uid;
+ cred.fc_mode = vs->perm & 0777;
+
+ return s->ops->link(&s->ctx, nfidp->path.data, vs->fullname.data, &cred);
}
static int v9fs_do_truncate(V9fsState *s, V9fsString *path, off_t size)
@@ -1778,7 +1788,7 @@ static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)
err = v9fs_do_mkdir(s, vs);
v9fs_create_post_mkdir(s, vs, err);
} else if (vs->perm & P9_STAT_MODE_SYMLINK) {
- err = v9fs_do_symlink(s, &vs->extension, &vs->fullname);
+ err = v9fs_do_symlink(s, vs);
v9fs_create_post_perms(s, vs, err);
} else if (vs->perm & P9_STAT_MODE_LINK) {
int32_t nfid = atoi(vs->extension.data);
@@ -1787,7 +1797,7 @@ static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)
err = -errno;
v9fs_post_create(s, vs, err);
}
- err = v9fs_do_link(s, &nfidp->path, &vs->fullname);
+ err = v9fs_do_link(s, nfidp, vs);
v9fs_create_post_perms(s, vs, err);
} else if (vs->perm & P9_STAT_MODE_DEVICE) {
char ctype;
--
1.6.5.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 6/6] virtio-9p: Implemented Security model for lstat and fstat
2010-05-10 20:23 [Qemu-devel] [PATCH 0/6] virtio-9p:Introducing security model for VirtFS Venkateswararao Jujjuri (JV)
` (4 preceding siblings ...)
2010-05-10 20:24 ` [Qemu-devel] [PATCH 5/6] virtio-9p: Implemented security model for symlink and link Venkateswararao Jujjuri (JV)
@ 2010-05-10 20:24 ` Venkateswararao Jujjuri (JV)
5 siblings, 0 replies; 7+ messages in thread
From: Venkateswararao Jujjuri (JV) @ 2010-05-10 20:24 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, Venkateswararao Jujjuri (JV)
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
---
hw/virtio-9p-local.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 63 insertions(+), 4 deletions(-)
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index 89b17f0..529de73 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -27,9 +27,40 @@ static const char *rpath(FsContext *ctx, const char *path)
return buffer;
}
-static int local_lstat(FsContext *ctx, const char *path, struct stat *stbuf)
+
+static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
{
- return lstat(rpath(ctx, path), stbuf);
+ int err;
+ err = lstat(rpath(fs_ctx, path), stbuf);
+ if (err) {
+ return err;
+ }
+ if (fs_ctx->fs_sm == sm_mapped) {
+ /* Actual credentials are part of extended attrs */
+ uid_t tmp_uid;
+ gid_t tmp_gid;
+ mode_t tmp_mode;
+ dev_t tmp_dev;
+ if (getxattr(rpath(fs_ctx, path), "user.virtfs.uid", &tmp_uid,
+ sizeof(uid_t)) > 0) {
+ stbuf->st_uid = tmp_uid;
+ }
+ if (getxattr(rpath(fs_ctx, path), "user.virtfs.gid", &tmp_gid,
+ sizeof(gid_t)) > 0) {
+ stbuf->st_gid = tmp_gid;
+ }
+ if (getxattr(rpath(fs_ctx, path), "user.virtfs.mode", &tmp_mode,
+ sizeof(mode_t)) > 0) {
+ stbuf->st_mode = tmp_mode;
+ }
+ if (S_ISCHR(tmp_mode) || S_ISCHR(tmp_mode)) {
+ if (getxattr(rpath(fs_ctx, path), "user.virtfs.rdev", &tmp_dev,
+ sizeof(dev_t)) > 0) {
+ stbuf->st_rdev = tmp_dev;
+ }
+ }
+ }
+ return err;
}
static void local_set_cred(FsCred *credp)
@@ -200,9 +231,37 @@ static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp)
return err;
}
-static int local_fstat(FsContext *ctx, int fd, struct stat *stbuf)
+static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf)
{
- return fstat(fd, stbuf);
+ int err;
+ err = fstat(fd, stbuf);
+ if (err) {
+ return err;
+ }
+ if (fs_ctx->fs_sm == sm_mapped) {
+ /* Actual credentials are part of extended attrs */
+ uid_t tmp_uid;
+ gid_t tmp_gid;
+ mode_t tmp_mode;
+ dev_t tmp_dev;
+
+ if (fgetxattr(fd, "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) {
+ stbuf->st_uid = tmp_uid;
+ }
+ if (fgetxattr(fd, "user.virtfs.gid", &tmp_gid, sizeof(gid_t)) > 0) {
+ stbuf->st_gid = tmp_gid;
+ }
+ if (fgetxattr(fd, "user.virtfs.mode", &tmp_mode, sizeof(mode_t)) > 0) {
+ stbuf->st_mode = tmp_mode;
+ }
+ if (S_ISCHR(tmp_mode) || S_ISCHR(tmp_mode)) {
+ if (fgetxattr(fd, "user.virtfs.rdev", &tmp_dev,
+ sizeof(dev_t)) > 0) {
+ stbuf->st_rdev = tmp_dev;
+ }
+ }
+ }
+ return err;
}
static int local_open2(FsContext *fs_ctx, const char *path, int flags,
--
1.6.5.2
^ permalink raw reply related [flat|nested] 7+ messages in thread