From: "M. Mohan Kumar" <mohan@in.ibm.com>
To: qemu-devel@nongnu.org, Stefan Hajnoczi <stefanha@gmail.com>
Subject: [Qemu-devel] [V8 PATCH 11/11] virtio-9p: Chroot environment for other functions
Date: Wed, 9 Mar 2011 22:46:00 +0530 [thread overview]
Message-ID: <1299690960-12007-12-git-send-email-mohan@in.ibm.com> (raw)
In-Reply-To: <1299690960-12007-1-git-send-email-mohan@in.ibm.com>
Add chroot functionality for systemcalls that can operate on a file
using relative directory file descriptor.
Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
---
hw/9pfs/virtio-9p-local.c | 156 ++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 139 insertions(+), 17 deletions(-)
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 1670e33..0157eb8 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -22,6 +22,7 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <attr/xattr.h>
+#include <libgen.h>
/* Helper routine to fill V9fsFileObjectRequest structure */
static int fill_fileobjectrequest(V9fsFileObjectRequest *request,
@@ -70,14 +71,41 @@ static int passthrough_request(FsContext *fs_ctx, const char *old_path,
return retval;
}
+/*
+ * Returns file descriptor of dirname(path)
+ * This fd can be used by *at functions
+ */
+static int get_dirfd(FsContext *fs_ctx, const char *path)
+{
+ V9fsFileObjectRequest request;
+ int fd;
+ char *dpath = qemu_strdup(path);
+
+ fd = fill_fileobjectrequest(&request, dirname(dpath), NULL);
+ if (fd < 0) {
+ qemu_free(dpath);
+ errno = -fd;
+ return -1;
+ }
+ request.data.type = T_OPEN;
+ fd = v9fs_request(fs_ctx, &request);
+ qemu_free(dpath);
+ if (fd < 0) {
+ errno = -fd;
+ fd = -1;
+ }
+ return fd;
+}
+
static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
{
int err;
- err = lstat(rpath(fs_ctx, path), stbuf);
- if (err) {
- return err;
- }
+
if (fs_ctx->fs_sm == SM_MAPPED) {
+ err = lstat(rpath(fs_ctx, path), stbuf);
+ if (err) {
+ return err;
+ }
/* Actual credentials are part of extended attrs */
uid_t tmp_uid;
gid_t tmp_gid;
@@ -99,6 +127,27 @@ static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
sizeof(dev_t)) > 0) {
stbuf->st_rdev = tmp_dev;
}
+ } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+ int pfd, serrno = 0;
+ char *tmp_path;
+
+ pfd = get_dirfd(fs_ctx, path);
+ if (pfd < 0) {
+ return -1;
+ }
+ tmp_path = qemu_strdup(path);
+ err = fstatat(pfd, basename(tmp_path), stbuf, AT_SYMLINK_NOFOLLOW);
+ if (err < 0) {
+ serrno = errno;
+ }
+ close(pfd);
+ qemu_free(tmp_path);
+ errno = serrno;
+ } else {
+ err = lstat(rpath(fs_ctx, path), stbuf);
+ if (err) {
+ return err;
+ }
}
return err;
}
@@ -163,9 +212,23 @@ static ssize_t local_readlink(FsContext *fs_ctx, const char *path,
} while (tsize == -1 && errno == EINTR);
close(fd);
return tsize;
- } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
- (fs_ctx->fs_sm == SM_NONE)) {
+ } else if (fs_ctx->fs_sm == SM_NONE) {
tsize = readlink(rpath(fs_ctx, path), buf, bufsz);
+ } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+ int pfd, serrno = 0;
+ char *tmp_path;
+ pfd = get_dirfd(fs_ctx, path);
+ if (pfd < 0) {
+ return -1;
+ }
+ tmp_path = qemu_strdup(path);
+ tsize = readlinkat(pfd, basename(tmp_path), buf, bufsz);
+ if (tsize < 0) {
+ serrno = errno;
+ }
+ close(pfd);
+ qemu_free(tmp_path);
+ errno = serrno;
}
return tsize;
}
@@ -257,8 +320,23 @@ static int local_chmod(FsContext *fs_ctx, const char *path, FsCred *credp)
{
if (fs_ctx->fs_sm == SM_MAPPED) {
return local_set_xattr(rpath(fs_ctx, path), credp);
- } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
- (fs_ctx->fs_sm == SM_NONE)) {
+ } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+ int pfd, err, serrno = 0;
+ char *tmp_path;
+ pfd = get_dirfd(fs_ctx, path);
+ if (pfd < 0) {
+ return -1;
+ }
+ tmp_path = qemu_strdup(path);
+ err = fchmodat(pfd, basename(tmp_path), credp->fc_mode, 0);
+ if (err == -1) {
+ serrno = errno;
+ }
+ qemu_free(tmp_path);
+ close(pfd);
+ errno = serrno;
+ return err;
+ } else if (fs_ctx->fs_sm == SM_NONE) {
return chmod(rpath(fs_ctx, path), credp->fc_mode);
}
return -1;
@@ -506,7 +584,21 @@ static int local_link(FsContext *fs_ctx, const char *oldpath,
static int local_truncate(FsContext *ctx, const char *path, off_t size)
{
- return truncate(rpath(ctx, path), size);
+ if (ctx->fs_sm == SM_PASSTHROUGH) {
+ int fd, retval, serrno;
+ fd = passthrough_request(ctx, NULL, path, O_RDWR, NULL, T_OPEN);
+ if (fd < 0) {
+ errno = -fd;
+ return -1;
+ }
+ retval = ftruncate(fd, size);
+ serrno = errno;
+ close(fd);
+ errno = serrno;
+ return retval;
+ } else {
+ return truncate(rpath(ctx, path), size);
+ }
}
static int local_rename(FsContext *ctx, const char *oldpath,
@@ -536,22 +628,52 @@ static int local_rename(FsContext *ctx, const char *oldpath,
static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp)
{
- if ((credp->fc_uid == -1 && credp->fc_gid == -1) ||
- (fs_ctx->fs_sm == SM_PASSTHROUGH)) {
+ if (fs_ctx->fs_sm != SM_PASSTHROUGH &&
+ (credp->fc_uid == -1 && credp->fc_gid == -1)) {
+ return lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid);
+ } else if (fs_ctx->fs_sm == SM_NONE) {
return lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid);
} else if (fs_ctx->fs_sm == SM_MAPPED) {
return local_set_xattr(rpath(fs_ctx, path), credp);
- } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
- (fs_ctx->fs_sm == SM_NONE)) {
- return lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid);
+ } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+ int pfd, err, serrno = 0;
+ char *old_path;
+ pfd = get_dirfd(fs_ctx, path);
+ if (pfd < 0) {
+ return -1;
+ }
+ old_path = qemu_strdup(path);
+ err = fchownat(pfd, basename(old_path), credp->fc_uid, credp->fc_gid,
+ AT_SYMLINK_NOFOLLOW);
+ if (err == -1) {
+ serrno = errno;
+ }
+ qemu_free(old_path);
+ close(pfd);
+ errno = serrno;
+ return err;
}
return -1;
}
-static int local_utimensat(FsContext *s, const char *path,
- const struct timespec *buf)
+static int local_utimensat(FsContext *fs_ctx, const char *path,
+ const struct timespec *buf)
{
- return qemu_utimensat(AT_FDCWD, rpath(s, path), buf, AT_SYMLINK_NOFOLLOW);
+ if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+ int fd, retval;
+ fd = passthrough_request(fs_ctx, NULL, path,
+ O_RDONLY | O_NONBLOCK | O_NOFOLLOW, NULL, T_OPEN);
+ if (fd < 0) {
+ errno = -fd;
+ return -1;
+ }
+ retval = futimens(fd, buf);
+ close(fd);
+ return retval;
+ } else {
+ return utimensat(AT_FDCWD, rpath(fs_ctx, path), buf,
+ AT_SYMLINK_NOFOLLOW);
+ }
}
static int local_remove(FsContext *ctx, const char *path)
--
1.7.3.4
next prev parent reply other threads:[~2011-03-09 17:16 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-09 17:15 [Qemu-devel] [V8 PATCH 00/11] virtio-9p: Use chroot to safely access files in passthrough security model M. Mohan Kumar
2011-03-09 17:15 ` [Qemu-devel] [V8 PATCH 01/11] Implement qemu_read_full M. Mohan Kumar
2011-03-09 17:15 ` [Qemu-devel] [V8 PATCH 02/11] virtio-9p: Enable CONFIG_THREAD if CONFIG_VIRTFS is enabled M. Mohan Kumar
2011-03-09 17:15 ` [Qemu-devel] [V8 PATCH 03/11] virtio-9p: Provide chroot worker side interfaces M. Mohan Kumar
2011-03-09 17:15 ` [Qemu-devel] [V8 PATCH 04/11] virtio-9p: Add qemu side interfaces for chroot environment M. Mohan Kumar
2011-03-09 17:15 ` [Qemu-devel] [V8 PATCH 05/11] virtio-9p: Add support to open a file in " M. Mohan Kumar
2011-03-10 11:09 ` [Qemu-devel] " Stefan Hajnoczi
2011-03-09 17:15 ` [Qemu-devel] [V8 PATCH 06/11] virtio-9p: Create support " M. Mohan Kumar
2011-03-09 17:15 ` [Qemu-devel] [V8 PATCH 07/11] virtio-9p: Support for creating special files M. Mohan Kumar
2011-03-09 17:15 ` [Qemu-devel] [V8 PATCH 08/11] virtio-9p: Add support for removing file or directory M. Mohan Kumar
2011-03-09 17:15 ` [Qemu-devel] [V8 PATCH 09/11] virtio-9p: Add support to rename M. Mohan Kumar
2011-03-09 17:15 ` [Qemu-devel] [V8 PATCH 10/11] virtio-9p: Move file post creation changes to none security model M. Mohan Kumar
2011-03-09 17:16 ` M. Mohan Kumar [this message]
2011-03-10 12:29 ` [Qemu-devel] Re: [V8 PATCH 11/11] virtio-9p: Chroot environment for other functions Stefan Hajnoczi
2011-03-11 5:54 ` Venkateswararao Jujjuri (JV)
2011-03-11 6:30 ` Stefan Hajnoczi
2011-03-11 15:23 ` 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=1299690960-12007-12-git-send-email-mohan@in.ibm.com \
--to=mohan@in.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).