[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 06/81] 9pfs: local: open/opendir: don't follow symli
From: |
Michael Roth |
Subject: |
[Qemu-devel] [PATCH 06/81] 9pfs: local: open/opendir: don't follow symlinks |
Date: |
Mon, 20 Mar 2017 18:07:30 -0500 |
From: Greg Kurz <address@hidden>
The local_open() and local_opendir() callbacks are vulnerable to symlink
attacks because they call:
(1) open(O_NOFOLLOW) which follows symbolic links in all path elements but
the rightmost one
(2) opendir() which follows symbolic links in all path elements
This patch converts both callbacks to use new helpers based on
openat_nofollow() to only open files and directories if they are
below the virtfs shared folder
This partly fixes CVE-2016-9602.
Signed-off-by: Greg Kurz <address@hidden>
Reviewed-by: Stefan Hajnoczi <address@hidden>
(cherry picked from commit 996a0d76d7e756e4023ef79bc37bfe629b9eaca7)
Signed-off-by: Greg Kurz <address@hidden>
Signed-off-by: Michael Roth <address@hidden>
---
hw/9pfs/9p-local.c | 37 +++++++++++++++++++++++++++----------
hw/9pfs/9p-local.h | 20 ++++++++++++++++++++
2 files changed, 47 insertions(+), 10 deletions(-)
create mode 100644 hw/9pfs/9p-local.h
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 12fc4fc..3a2b659 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -13,6 +13,7 @@
#include "qemu/osdep.h"
#include "9p.h"
+#include "9p-local.h"
#include "9p-xattr.h"
#include "9p-util.h"
#include "fsdev/qemu-fsdev.h" /* local_ops */
@@ -48,6 +49,24 @@ typedef struct {
int mountfd;
} LocalData;
+int local_open_nofollow(FsContext *fs_ctx, const char *path, int flags,
+ mode_t mode)
+{
+ LocalData *data = fs_ctx->private;
+
+ /* All paths are relative to the path data->mountfd points to */
+ while (*path == '/') {
+ path++;
+ }
+
+ return relative_openat_nofollow(data->mountfd, path, flags, mode);
+}
+
+int local_opendir_nofollow(FsContext *fs_ctx, const char *path)
+{
+ return local_open_nofollow(fs_ctx, path, O_DIRECTORY | O_RDONLY, 0);
+}
+
#define VIRTFS_META_DIR ".virtfs_metadata"
static char *local_mapped_attr_path(FsContext *ctx, const char *path)
@@ -359,13 +378,9 @@ static int local_closedir(FsContext *ctx, V9fsFidOpenState
*fs)
static int local_open(FsContext *ctx, V9fsPath *fs_path,
int flags, V9fsFidOpenState *fs)
{
- char *buffer;
- char *path = fs_path->data;
int fd;
- buffer = rpath(ctx, path);
- fd = open(buffer, flags | O_NOFOLLOW);
- g_free(buffer);
+ fd = local_open_nofollow(ctx, fs_path->data, flags, 0);
if (fd == -1) {
return -1;
}
@@ -376,13 +391,15 @@ static int local_open(FsContext *ctx, V9fsPath *fs_path,
static int local_opendir(FsContext *ctx,
V9fsPath *fs_path, V9fsFidOpenState *fs)
{
- char *buffer;
- char *path = fs_path->data;
+ int dirfd;
DIR *stream;
- buffer = rpath(ctx, path);
- stream = opendir(buffer);
- g_free(buffer);
+ dirfd = local_opendir_nofollow(ctx, fs_path->data);
+ if (dirfd == -1) {
+ return -1;
+ }
+
+ stream = fdopendir(dirfd);
if (!stream) {
return -1;
}
diff --git a/hw/9pfs/9p-local.h b/hw/9pfs/9p-local.h
new file mode 100644
index 0000000..32c7274
--- /dev/null
+++ b/hw/9pfs/9p-local.h
@@ -0,0 +1,20 @@
+/*
+ * 9p local backend utilities
+ *
+ * Copyright IBM, Corp. 2017
+ *
+ * Authors:
+ * Greg Kurz <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QEMU_9P_LOCAL_H
+#define QEMU_9P_LOCAL_H
+
+int local_open_nofollow(FsContext *fs_ctx, const char *path, int flags,
+ mode_t mode);
+int local_opendir_nofollow(FsContext *fs_ctx, const char *path);
+
+#endif
--
2.7.4
- [Qemu-devel] [PATCH 67/81] target/sparc: Restore ldstub of odd asis, (continued)
- [Qemu-devel] [PATCH 67/81] target/sparc: Restore ldstub of odd asis, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 68/81] apic: reset apic_delivered global variable on machine reset, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 41/81] ui/gtk: fix crash at startup when no console is available, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 44/81] qemu-thread: fix qemu_thread_set_name() race in qemu_thread_create(), Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 49/81] char: fix ctrl-a b not working, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 51/81] tcg/aarch64: Fix tcg_out_movi, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 52/81] ui: use evdev keymap when running under wayland, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 56/81] cirrus: fix oob access issue (CVE-2017-2615), Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 70/81] qga: ignore EBUSY when freezing a filesystem, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 75/81] NetRxPkt: Do not try to pull more data than present, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 06/81] 9pfs: local: open/opendir: don't follow symlinks,
Michael Roth <=
- [Qemu-devel] [PATCH 59/81] target/s390x: use "qemu" cpu model in user mode, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 74/81] NetRxPkt: Fix memory corruption on VLAN header stripping, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 69/81] target-i386: correctly propagate retaddr into SVM helpers, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 08/81] 9pfs: local: llistxattr: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 61/81] block/nfs: fix NULL pointer dereference in URI parsing, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 05/81] 9pfs: local: keep a file descriptor on the shared folder, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 64/81] vnc: do not disconnect on EAGAIN, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 63/81] sd: sdhci: check data length during dma_memory_read, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 76/81] NetRxPkt: Account buffer with ETH header in IOV length, Michael Roth, 2017/03/20
- [Qemu-devel] [PATCH 66/81] block/vmdk: Fix the endian problem of buf_len and lba, Michael Roth, 2017/03/20