From 0ceb092e35f9d8793d64d86194ec9463718dffa3 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 20 May 2013 19:43:15 +0530 Subject: 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" Signed-off-by: Aneesh Kumar K.V --- hw/9pfs/virtio-9p-local.c | 48 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) (limited to 'hw/9pfs') 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; -- cgit v1.2.1