Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
qemu-linux-user.11147
0372-9pfs-local-open-opendir-don-t-follo.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0372-9pfs-local-open-opendir-don-t-follo.patch of Package qemu-linux-user.11147
From c6aa5e941e6904eb6c04f2e5a814ff96eb2e8821 Mon Sep 17 00:00:00 2001 From: Greg Kurz <groug@kaod.org> Date: Sun, 26 Feb 2017 23:42:18 +0100 Subject: [PATCH] 9pfs: local: open/opendir: don't follow symlinks 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 <groug@kaod.org> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> (cherry picked from commit 996a0d76d7e756e4023ef79bc37bfe629b9eaca7) [BR: Fix and/or infrastructure for BSC#1020427 CVE-2016-9602] Signed-off-by: Bruce Rogers <brogers@suse.com> --- hw/9pfs/9p-local.c | 37 +++++++++++++++++++++++++++---------- hw/9pfs/9p-local.h | 20 ++++++++++++++++++++ 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index e31a5ac69f..477c555f4f 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -12,6 +12,7 @@ */ #include "9p.h" +#include "9p-local.h" #include "9p-xattr.h" #include "9p-util.h" #include <arpa/inet.h> @@ -44,6 +45,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) @@ -358,13 +377,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; } @@ -375,13 +390,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 0000000000..32c72749d9 --- /dev/null +++ b/hw/9pfs/9p-local.h @@ -0,0 +1,20 @@ +/* + * 9p local backend utilities + * + * Copyright IBM, Corp. 2017 + * + * Authors: + * Greg Kurz <groug@kaod.org> + * + * 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
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor