From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:40861) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uf78O-00060s-AD for qemu-devel@nongnu.org; Wed, 22 May 2013 07:23:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Uf78M-0007b5-6d for qemu-devel@nongnu.org; Wed, 22 May 2013 07:23:08 -0400 Received: from e28smtp02.in.ibm.com ([122.248.162.2]:54743) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uf78L-0007St-J1 for qemu-devel@nongnu.org; Wed, 22 May 2013 07:23:06 -0400 Received: from /spool/local by e28smtp02.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 22 May 2013 16:46:22 +0530 Received: from d28relay04.in.ibm.com (d28relay04.in.ibm.com [9.184.220.61]) by d28dlp01.in.ibm.com (Postfix) with ESMTP id 956FBE004F for ; Wed, 22 May 2013 16:55:32 +0530 (IST) Received: from d28av03.in.ibm.com (d28av03.in.ibm.com [9.184.220.65]) by d28relay04.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id r4MBMrIU59310106 for ; Wed, 22 May 2013 16:52:53 +0530 Received: from d28av03.in.ibm.com (loopback [127.0.0.1]) by d28av03.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id r4MBMwbl013051 for ; Wed, 22 May 2013 21:22:58 +1000 From: "Aneesh Kumar K.V" Date: Wed, 22 May 2013 16:52:54 +0530 Message-Id: <1369221774-10735-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH] hw/9pfs: Use O_NOFOLLOW when opening files on server List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aliguori@us.ibm.com, "Aneesh Kumar K.V" From: "Aneesh Kumar K.V" 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-handle.c | 2 +- hw/9pfs/virtio-9p-local.c | 48 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/hw/9pfs/virtio-9p-handle.c b/hw/9pfs/virtio-9p-handle.c index fe8e0ed..e2a89e3 100644 --- a/hw/9pfs/virtio-9p-handle.c +++ b/hw/9pfs/virtio-9p-handle.c @@ -608,7 +608,7 @@ static int handle_init(FsContext *ctx) struct file_handle fh; struct handle_data *data = g_malloc(sizeof(struct handle_data)); - data->mountfd = open(ctx->fs_root, O_DIRECTORY); + data->mountfd = open(ctx->fs_root, O_DIRECTORY | O_NOFOLLOW); if (data->mountfd < 0) { ret = data->mountfd; goto err_out; diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index 87aa75d..fc93e9e 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; -- 1.8.1.2