summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkateswararao Jujjuri (JV) <jvrao@linux.vnet.ibm.com>2010-06-14 13:34:48 -0700
committerAnthony Liguori <aliguori@us.ibm.com>2010-06-22 15:15:51 -0500
commit1c29331248d82e5a9caaf7974756a9d8bd5cd1e5 (patch)
tree500c94c940395e4ccc165f163513306456cc87a1
parent879c28133dfa54b780dffbb29e4dcfc6581f6281 (diff)
downloadqemu-1c29331248d82e5a9caaf7974756a9d8bd5cd1e5.tar.gz
virtio-9p: Implement Security model for mknod
Mapped mode stores extended attributes in the user space of the extended attributes. Given that the user space extended attributes are available to regular files only, special files are created as regular files on the fileserver and appropriate mode bits are added to the extended attributes. This method presents all special files and symlinks as regular files on the fileserver while they are represented as special files on the guest mount. On Host/Fileserver: -rw-------. 1 virfsuid virtfsgid 0 2010-05-11 09:36 afifo -rw-------. 1 virfsuid virtfsgid 0 2010-05-11 09:32 blkdev -rw-------. 1 virfsuid virtfsgid 0 2010-05-11 09:33 chardev On Guest/Client: prw-r--r-- 1 guestuser guestuser 0 2010-05-11 12:36 afifo brw-r--r-- 1 guestuser guestuser 0, 0 2010-05-11 12:32 blkdev crw-r--r-- 1 guestuser guestuser 4, 5 2010-05-11 12:33 chardev In the passthrough securit model, specifal files are directly created on the fileserver. But the user credential Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--hw/file-op-9p.h2
-rw-r--r--hw/virtio-9p-local.c34
-rw-r--r--hw/virtio-9p.c14
3 files changed, 43 insertions, 7 deletions
diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h
index 0808630fe4..5bc61b5dc1 100644
--- a/hw/file-op-9p.h
+++ b/hw/file-op-9p.h
@@ -51,7 +51,7 @@ typedef struct FileOperations
ssize_t (*readlink)(FsContext *, const char *, char *, size_t);
int (*chmod)(FsContext *, const char *, FsCred *);
int (*chown)(FsContext *, const char *, FsCred *);
- int (*mknod)(FsContext *, const char *, mode_t, dev_t);
+ int (*mknod)(FsContext *, const char *, FsCred *);
int (*mksock)(FsContext *, const char *);
int (*utime)(FsContext *, const char *, const struct utimbuf *);
int (*remove)(FsContext *, const char *);
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index 711f2b5ca1..791a8ba088 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -195,9 +195,39 @@ static int local_chmod(FsContext *fs_ctx, const char *path, FsCred *credp)
return -1;
}
-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);
+ int err = -1;
+ int serrno = 0;
+
+ /* 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) {
+ return err;
+ }
+ local_set_xattr(rpath(fs_ctx, path), credp);
+ if (err == -1) {
+ serrno = errno;
+ goto err_end;
+ }
+ } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+ err = mknod(rpath(fs_ctx, path), credp->fc_mode, credp->fc_rdev);
+ if (err == -1) {
+ return err;
+ }
+ err = local_post_create_passthrough(fs_ctx, path, credp);
+ if (err == -1) {
+ serrno = errno;
+ goto err_end;
+ }
+ }
+ return err;
+
+err_end:
+ remove(rpath(fs_ctx, path));
+ errno = serrno;
+ return err;
}
static int local_mksock(FsContext *ctx2, const char *path)
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 1a25e96955..d276db3762 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -160,9 +160,15 @@ static int v9fs_do_chmod(V9fsState *s, V9fsString *path, mode_t mode)
return s->ops->chmod(&s->ctx, path->data, &cred);
}
-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);
+ 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_mksock(V9fsState *s, V9fsString *path)
@@ -1825,10 +1831,10 @@ 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);