summaryrefslogtreecommitdiff
path: root/hw/9pfs
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2013-05-20 19:43:15 +0530
committerAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2013-05-28 15:23:12 +0530
commit0ceb092e35f9d8793d64d86194ec9463718dffa3 (patch)
tree983262d0521c46cda9621151f41110df9b44d6d3 /hw/9pfs
parentaed858ce10ef09c7bdf03f73e75e772f567c74cd (diff)
downloadqemu-0ceb092e35f9d8793d64d86194ec9463718dffa3.tar.gz
hw/9pfs: Use O_NOFOLLOW when opening files on server
9p server should never follow a symlink. So use O_NOFOLLOW with all open syscall Tested-by: "M. Mohan Kumar" <mohan@in.ibm.com> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Diffstat (limited to 'hw/9pfs')
-rw-r--r--hw/9pfs/virtio-9p-local.c48
1 files changed, 41 insertions, 7 deletions
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 87aa75d923..fc93e9e6e8 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -59,6 +59,33 @@ static const char *local_mapped_attr_path(FsContext *ctx,
return buffer;
}
+static FILE *local_fopen(const char *path, const char *mode)
+{
+ int fd, o_mode = 0;
+ FILE *fp;
+ int flags = O_NOFOLLOW;
+ /*
+ * only supports two modes
+ */
+ if (mode[0] == 'r') {
+ flags |= O_RDONLY;
+ } else if (mode[0] == 'w') {
+ flags |= O_WRONLY | O_TRUNC | O_CREAT;
+ o_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+ } else {
+ return NULL;
+ }
+ fd = open(path, flags, o_mode);
+ if (fd == -1) {
+ return NULL;
+ }
+ fp = fdopen(fd, mode);
+ if (!fp) {
+ close(fd);
+ }
+ return fp;
+}
+
#define ATTR_MAX 100
static void local_mapped_file_attr(FsContext *ctx, const char *path,
struct stat *stbuf)
@@ -68,7 +95,7 @@ static void local_mapped_file_attr(FsContext *ctx, const char *path,
char attr_path[PATH_MAX];
local_mapped_attr_path(ctx, path, attr_path);
- fp = fopen(attr_path, "r");
+ fp = local_fopen(attr_path, "r");
if (!fp) {
return;
}
@@ -152,7 +179,7 @@ static int local_set_mapped_file_attr(FsContext *ctx,
char attr_path[PATH_MAX];
int uid = -1, gid = -1, mode = -1, rdev = -1;
- fp = fopen(local_mapped_attr_path(ctx, path, attr_path), "r");
+ fp = local_fopen(local_mapped_attr_path(ctx, path, attr_path), "r");
if (!fp) {
goto create_map_file;
}
@@ -179,7 +206,7 @@ create_map_file:
}
update_map_file:
- fp = fopen(attr_path, "w");
+ fp = local_fopen(attr_path, "w");
if (!fp) {
ret = -1;
goto err_out;
@@ -316,7 +343,7 @@ static int local_open(FsContext *ctx, V9fsPath *fs_path,
char buffer[PATH_MAX];
char *path = fs_path->data;
- fs->fd = open(rpath(ctx, path, buffer), flags);
+ fs->fd = open(rpath(ctx, path, buffer), flags | O_NOFOLLOW);
return fs->fd;
}
@@ -601,6 +628,11 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
V9fsString fullname;
char buffer[PATH_MAX];
+ /*
+ * Mark all the open to not follow symlinks
+ */
+ flags |= O_NOFOLLOW;
+
v9fs_string_init(&fullname);
v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
path = fullname.data;
@@ -676,8 +708,9 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
int fd;
ssize_t oldpath_size, write_size;
- fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR,
- SM_LOCAL_MODE_BITS);
+ fd = open(rpath(fs_ctx, newpath, buffer),
+ O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW,
+ SM_LOCAL_MODE_BITS);
if (fd == -1) {
err = fd;
goto out;
@@ -705,7 +738,8 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
int fd;
ssize_t oldpath_size, write_size;
- fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR,
+ fd = open(rpath(fs_ctx, newpath, buffer),
+ O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW,
SM_LOCAL_MODE_BITS);
if (fd == -1) {
err = fd;