From: Anthony Liguori <aliguori@linux.vnet.ibm.com>
To: "Venkateswararao Jujjuri (JV)" <jvrao@linux.vnet.ibm.com>
Cc: aliguori@us.ibm.com, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH -V3 3/7] virtio-9p: modify create/open2 and mkdir for new security model.
Date: Mon, 24 May 2010 15:12:19 -0500 [thread overview]
Message-ID: <4BFADDA3.2070107@linux.vnet.ibm.com> (raw)
In-Reply-To: <1274477170-7658-4-git-send-email-jvrao@linux.vnet.ibm.com>
On 05/21/2010 04:26 PM, Venkateswararao Jujjuri (JV) wrote:
> 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 | 139 +++++++++++++++++++++++++++++++++++---------------
> hw/virtio-9p.c | 42 ++++++++++-----
> 3 files changed, 148 insertions(+), 56 deletions(-)
>
> diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h
> index 2934ff1..2cf7d27 100644
> --- a/hw/file-op-9p.h
> +++ b/hw/file-op-9p.h
> @@ -19,13 +19,32 @@
> #include<sys/stat.h>
> #include<sys/uio.h>
> #include<sys/vfs.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 */
>
Should use caps.
> +} 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 *);
> @@ -43,7 +62,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 *);
> @@ -51,7 +70,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 78960ac..14fd3d9 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>
>
This is probably not something that can be included unconditionally.
Regards,
Anthony Liguori
> static const char *rpath(FsContext *ctx, const char *path)
> {
> @@ -31,47 +32,39 @@ 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 int local_set_xattr(const char *path, FsCred *credp)
> {
> - struct passwd *pw;
> - gid_t groups[33];
> - int ngroups;
> - static uid_t cur_uid = -1;
> -
> - if (cur_uid == uid) {
> - return 0;
> - }
> -
> - if (setreuid(0, 0)) {
> - return -1;
> - }
> -
> - pw = getpwuid(uid);
> - if (pw == NULL) {
> - return -1;
> + int err;
> + if (credp->fc_uid != -1) {
> + err = setxattr(path, "user.virtfs.uid",&credp->fc_uid, sizeof(uid_t),
> + 0);
> + 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_gid, sizeof(gid_t),
> + 0);
> + if (err) {
> + return err;
> + }
> }
> -
> - if (setgroups(ngroups, groups)) {
> - return -1;
> - }
> -
> - if (setregid(-1, pw->pw_gid)) {
> - return -1;
> + if (credp->fc_mode != -1) {
> + err = setxattr(path, "user.virtfs.mode",&credp->fc_mode,
> + sizeof(mode_t), 0);
> + if (err) {
> + return err;
> + }
> }
> -
> - if (setreuid(-1, uid)) {
> - return -1;
> + if (credp->fc_rdev != -1) {
> + err = setxattr(path, "user.virtfs.rdev",&credp->fc_rdev,
> + sizeof(dev_t), 0);
> + 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 +161,39 @@ 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) {
> + goto err_end;
> + }
> + } else if (fs_ctx->fs_sm == sm_passthrough) {
> + err = mkdir(rpath(fs_ctx, path), credp->fc_mode);
> + if (err == -1) {
> + return err;
> + }
> + err = chmod(rpath(fs_ctx, path), credp->fc_mode& 07777);
> + if (err == -1) {
> + goto err_end;
> + }
> + err = chown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid);
> + if (err == -1) {
> + goto err_end;
> + }
> + }
> + return err;
> +
> +err_end:
> + remove(rpath(fs_ctx, path));
> + return err;
> }
>
> static int local_fstat(FsContext *ctx, int fd, struct stat *stbuf)
> @@ -178,9 +201,44 @@ 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;
> + int err = -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) {
> + return fd;
> + }
> + 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) {
> + goto err_end;
> + }
> + } else if (fs_ctx->fs_sm == sm_passthrough) {
> + fd = open(rpath(fs_ctx, path), flags, credp->fc_mode);
> + if (fd == -1) {
> + return fd;
> + }
> + err = chmod(rpath(fs_ctx, path), credp->fc_mode& 07777);
> + if (err == -1) {
> + goto err_end;
> + }
> + err = chown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid);
> + if (err == -1) {
> + goto err_end;
> + }
> + }
> + return fd;
> +
> +err_end:
> + close(fd);
> + remove(rpath(fs_ctx, path));
> + return err;
> }
>
> static int local_symlink(FsContext *ctx, const char *oldpath,
> @@ -269,7 +327,6 @@ static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf)
>
> 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 fda3c4a..c8bd5da 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;
> }
> }
> @@ -1762,7 +1778,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);
> @@ -1809,9 +1825,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);
> }
>
> @@ -2322,10 +2336,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"
>
next prev parent reply other threads:[~2010-05-24 20:12 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-21 21:26 [Qemu-devel] [PATCH-V2 0/7] virtio-9p:Introducing security model for VirtFS Venkateswararao Jujjuri (JV)
2010-05-21 21:26 ` [Qemu-devel] [PATCH -V3 1/7] virtio-9p: Introduces an option to specify the security model Venkateswararao Jujjuri (JV)
2010-05-24 20:10 ` Anthony Liguori
2010-05-21 21:26 ` [Qemu-devel] [PATCH -V3 2/7] virtio-9p: Rearrange fileop structures Venkateswararao Jujjuri (JV)
2010-05-25 18:07 ` Sripathi Kodi
2010-05-26 20:21 ` Venkateswararao Jujjuri (JV)
2010-05-21 21:26 ` [Qemu-devel] [PATCH -V3 3/7] virtio-9p: modify create/open2 and mkdir for new security model Venkateswararao Jujjuri (JV)
2010-05-24 20:12 ` Anthony Liguori [this message]
2010-05-21 21:26 ` [Qemu-devel] [PATCH -V3 4/7] virtio-9p: Implement Security model for mknod related files Venkateswararao Jujjuri (JV)
2010-05-21 21:26 ` [Qemu-devel] [PATCH -V3 5/7] virtio-9p: Implemented security model for symlink and link Venkateswararao Jujjuri (JV)
2010-05-24 20:13 ` Anthony Liguori
2010-05-21 21:26 ` [Qemu-devel] [PATCH -V3 6/7] virtio-9p: Implemented Security model for lstat and fstat Venkateswararao Jujjuri (JV)
2010-05-21 21:26 ` [Qemu-devel] [PATCH -V3 7/7] virtio-9p: Implemented security model for chown and chgrp Venkateswararao Jujjuri (JV)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4BFADDA3.2070107@linux.vnet.ibm.com \
--to=aliguori@linux.vnet.ibm.com \
--cc=aliguori@us.ibm.com \
--cc=jvrao@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.