[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 26/81] 9pfs: local: mkdir: don't follow symlinks
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 26/81] 9pfs: local: mkdir: don't follow symlinks |
Date: |
Mon, 20 Mar 2017 18:07:50 -0500 |
From: Greg Kurz <address@hidden>
The local_mkdir() callback is vulnerable to symlink attacks because it
calls:
(1) mkdir() which follows symbolic links for all path elements but the
rightmost one
(2) local_set_xattr()->setxattr() which follows symbolic links for all
path elements
(3) local_set_mapped_file_attr() which calls in turn local_fopen() and
mkdir(), both functions following symbolic links for all path
elements but the rightmost one
(4) local_post_create_passthrough() which calls in turn lchown() and
chmod(), both functions also following symbolic links
This patch converts local_mkdir() to rely on opendir_nofollow() and
mkdirat() to fix (1), as well as local_set_xattrat(),
local_set_mapped_file_attrat() and local_set_cred_passthrough() to
fix (2), (3) and (4) respectively.
The mapped and mapped-file security modes are supposed to be identical,
except for the place where credentials and file modes are stored. While
here, we also make that explicit by sharing the call to mkdirat().
This partly fixes CVE-2016-9602.
Signed-off-by: Greg Kurz <address@hidden>
Reviewed-by: Stefan Hajnoczi <address@hidden>
(cherry picked from commit 3f3a16990b09e62d787bd2eb2dd51aafbe90019a)
Signed-off-by: Greg Kurz <address@hidden>
Signed-off-by: Michael Roth <address@hidden>
---
hw/9pfs/9p-local.c | 55 ++++++++++++++++++++----------------------------------
1 file changed, 20 insertions(+), 35 deletions(-)
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index f71cc11..76ac205 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -800,62 +800,47 @@ out:
static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
const char *name, FsCred *credp)
{
- char *path;
int err = -1;
- int serrno = 0;
- V9fsString fullname;
- char *buffer = NULL;
+ int dirfd;
- v9fs_string_init(&fullname);
- v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
- path = fullname.data;
+ dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
+ if (dirfd == -1) {
+ return -1;
+ }
- /* Determine the security model */
- if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
- buffer = rpath(fs_ctx, path);
- err = mkdir(buffer, SM_LOCAL_DIR_MODE_BITS);
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
+ fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+ err = mkdirat(dirfd, name, SM_LOCAL_DIR_MODE_BITS);
if (err == -1) {
goto out;
}
- credp->fc_mode = credp->fc_mode|S_IFDIR;
- err = local_set_xattr(buffer, credp);
- if (err == -1) {
- serrno = errno;
- goto err_end;
- }
- } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
- buffer = rpath(fs_ctx, path);
- err = mkdir(buffer, SM_LOCAL_DIR_MODE_BITS);
- if (err == -1) {
- goto out;
+ credp->fc_mode = credp->fc_mode | S_IFDIR;
+
+ if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
+ err = local_set_xattrat(dirfd, name, credp);
+ } else {
+ err = local_set_mapped_file_attrat(dirfd, name, credp);
}
- credp->fc_mode = credp->fc_mode|S_IFDIR;
- err = local_set_mapped_file_attr(fs_ctx, path, credp);
if (err == -1) {
- serrno = errno;
goto err_end;
}
- } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
- (fs_ctx->export_flags & V9FS_SM_NONE)) {
- buffer = rpath(fs_ctx, path);
- err = mkdir(buffer, credp->fc_mode);
+ } else if (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH ||
+ fs_ctx->export_flags & V9FS_SM_NONE) {
+ err = mkdirat(dirfd, name, credp->fc_mode);
if (err == -1) {
goto out;
}
- err = local_post_create_passthrough(fs_ctx, path, credp);
+ err = local_set_cred_passthrough(fs_ctx, dirfd, name, credp);
if (err == -1) {
- serrno = errno;
goto err_end;
}
}
goto out;
err_end:
- remove(buffer);
- errno = serrno;
+ unlinkat_preserve_errno(dirfd, name, AT_REMOVEDIR);
out:
- g_free(buffer);
- v9fs_string_free(&fullname);
+ close_preserve_errno(dirfd);
return err;
}
--
2.7.4
- [Qemu-stable] [PATCH 01/81] 9pfs: local: move xattr security ops to 9p-xattr.c, (continued)
- [Qemu-stable] [PATCH 01/81] 9pfs: local: move xattr security ops to 9p-xattr.c, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 25/81] 9pfs: local: mknod: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 22/81] 9pfs: local: chmod: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 27/81] 9pfs: local: open2: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 28/81] 9pfs: local: drop unused code, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 31/81] 9pfs: fail local_statfs() earlier, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 02/81] 9pfs: remove side-effects in local_init(), Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 35/81] machine: Convert abstract typename on compat_props to subclass names, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 24/81] 9pfs: local: symlink: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 29/81] 9pfs: fix bogus fd check in local_remove(), Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 26/81] 9pfs: local: mkdir: don't follow symlinks,
Michael Roth <=
- [Qemu-stable] [PATCH 30/81] 9pfs: fix fd leak in local_opendir(), Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 38/81] virtio: fix vq->inuse recalc after migr, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 03/81] 9pfs: remove side-effects in local_open() and local_opendir(), Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 46/81] exec: Add missing rcu_read_unlock, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 50/81] tcg/aarch64: Fix addsub2 for 0+C, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 41/81] ui/gtk: fix crash at startup when no console is available, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 33/81] 9pfs: fix O_PATH build break with older glibc versions, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 34/81] 9pfs: fix vulnerability in openat_dir() and local_unlinkat_common(), Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 45/81] virtio-crypto: fix possible integer and heap overflow, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 37/81] pci: fix error message for express slots, Michael Roth, 2017/03/20