diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2013-05-29 08:13:20 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2013-05-29 08:13:20 -0500 |
commit | 338ea905e948613607c98346e127fc9472c57f0d (patch) | |
tree | beec239d48bedbfee122cec0b939363efd2291c1 | |
parent | 1afd566ce921493a13b3878662b5320aab7645d0 (diff) | |
parent | db431f6adc881a0758512cd765b3108209013512 (diff) | |
download | qemu-338ea905e948613607c98346e127fc9472c57f0d.tar.gz qemu-338ea905e948613607c98346e127fc9472c57f0d.tar.bz2 qemu-338ea905e948613607c98346e127fc9472c57f0d.zip |
Merge remote-tracking branch 'aneesh/for-upstream' into staging
# By Aneesh Kumar K.V (3) and Gabriel de Perthuis (1)
# Via Aneesh Kumar K.V
* aneesh/for-upstream:
hw/9pfs: Be robust against paths without FS_IOC_GETVERSION
hw/9pfs: Use O_NOFOLLOW when opening files on server
hw/9pfs: use O_NOFOLLOW for mapped readlink operation
hw/9pfs: Fix segfault with 9p2000.u
Message-id: 87zjvevx4s.fsf@linux.vnet.ibm.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r-- | hw/9pfs/cofile.c | 4 | ||||
-rw-r--r-- | hw/9pfs/virtio-9p-local.c | 50 | ||||
-rw-r--r-- | hw/9pfs/virtio-9p.c | 2 |
3 files changed, 47 insertions, 9 deletions
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c index 2efebf3571..194c1306c6 100644 --- a/hw/9pfs/cofile.c +++ b/hw/9pfs/cofile.c @@ -38,6 +38,10 @@ int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode, }); v9fs_path_unlock(s); } + /* The ioctl may not be supported depending on the path */ + if (err == -ENOTTY) { + err = 0; + } return err; } diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index 6ece6f7d1c..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; @@ -284,7 +311,7 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path, if ((fs_ctx->export_flags & V9FS_SM_MAPPED) || (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE)) { int fd; - fd = open(rpath(fs_ctx, path, buffer), O_RDONLY); + fd = open(rpath(fs_ctx, path, buffer), O_RDONLY | O_NOFOLLOW); if (fd == -1) { return -1; } @@ -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; diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 296f66f293..8cbb8ae32a 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -658,7 +658,7 @@ static mode_t v9mode_to_mode(uint32_t mode, V9fsString *extension) ret |= S_IFIFO; } if (mode & P9_STAT_MODE_DEVICE) { - if (extension && extension->data[0] == 'c') { + if (extension->size && extension->data[0] == 'c') { ret |= S_IFCHR; } else { ret |= S_IFBLK; |