[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 12/81] 9pfs: local: remove: don't follow symlinks
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 12/81] 9pfs: local: remove: don't follow symlinks |
Date: |
Mon, 20 Mar 2017 18:07:36 -0500 |
From: Greg Kurz <address@hidden>
The local_remove() callback is vulnerable to symlink attacks because it
calls:
(1) lstat() which follows symbolic links in all path elements but the
rightmost one
(2) remove() which follows symbolic links in all path elements but the
rightmost one
This patch converts local_remove() to rely on opendir_nofollow(),
fstatat(AT_SYMLINK_NOFOLLOW) to fix (1) and unlinkat() to fix (2).
This partly fixes CVE-2016-9602.
Signed-off-by: Greg Kurz <address@hidden>
Reviewed-by: Stefan Hajnoczi <address@hidden>
(cherry picked from commit a0e640a87210b1e986bcd4e7f7de03beb3db0a4a)
Signed-off-by: Greg Kurz <address@hidden>
Signed-off-by: Michael Roth <address@hidden>
---
hw/9pfs/9p-local.c | 64 ++++++++++++++++++------------------------------------
1 file changed, 21 insertions(+), 43 deletions(-)
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index a72adb8..9caee0e 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -1022,54 +1022,32 @@ err_out:
static int local_remove(FsContext *ctx, const char *path)
{
- int err;
struct stat stbuf;
- char *buffer;
+ char *dirpath = g_path_get_dirname(path);
+ char *name = g_path_get_basename(path);
+ int flags = 0;
+ int dirfd;
+ int err = -1;
- if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
- buffer = rpath(ctx, path);
- err = lstat(buffer, &stbuf);
- g_free(buffer);
- if (err) {
- goto err_out;
- }
- /*
- * If directory remove .virtfs_metadata contained in the
- * directory
- */
- if (S_ISDIR(stbuf.st_mode)) {
- buffer = g_strdup_printf("%s/%s/%s", ctx->fs_root,
- path, VIRTFS_META_DIR);
- err = remove(buffer);
- g_free(buffer);
- if (err < 0 && errno != ENOENT) {
- /*
- * We didn't had the .virtfs_metadata file. May be file created
- * in non-mapped mode ?. Ignore ENOENT.
- */
- goto err_out;
- }
- }
- /*
- * Now remove the name from parent directory
- * .virtfs_metadata directory
- */
- buffer = local_mapped_attr_path(ctx, path);
- err = remove(buffer);
- g_free(buffer);
- if (err < 0 && errno != ENOENT) {
- /*
- * We didn't had the .virtfs_metadata file. May be file created
- * in non-mapped mode ?. Ignore ENOENT.
- */
- goto err_out;
- }
+ dirfd = local_opendir_nofollow(ctx, dirpath);
+ if (dirfd) {
+ goto out;
}
- buffer = rpath(ctx, path);
- err = remove(buffer);
- g_free(buffer);
+ if (fstatat(dirfd, path, &stbuf, AT_SYMLINK_NOFOLLOW) < 0) {
+ goto err_out;
+ }
+
+ if (S_ISDIR(stbuf.st_mode)) {
+ flags |= AT_REMOVEDIR;
+ }
+
+ err = local_unlinkat_common(ctx, dirfd, name, flags);
err_out:
+ close_preserve_errno(dirfd);
+out:
+ g_free(name);
+ g_free(dirpath);
return err;
}
--
2.7.4
- [Qemu-stable] [PATCH 00/81] Patch Round-up for stable 2.8.1, freeze on 2017-03-27, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 10/81] 9pfs: local: lremovexattr: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 11/81] 9pfs: local: unlinkat: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 09/81] 9pfs: local: lsetxattr: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 16/81] 9pfs: local: readlink: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 13/81] 9pfs: local: utimensat: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 15/81] 9pfs: local: truncate: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 12/81] 9pfs: local: remove: don't follow symlinks,
Michael Roth <=
- [Qemu-stable] [PATCH 17/81] 9pfs: local: lstat: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 18/81] 9pfs: local: renameat: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 14/81] 9pfs: local: statfs: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 19/81] 9pfs: local: rename: use renameat, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 23/81] 9pfs: local: chown: don't follow symlinks, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 20/81] 9pfs: local: improve error handling in link op, Michael Roth, 2017/03/20
- [Qemu-stable] [PATCH 21/81] 9pfs: local: link: don't follow symlinks, Michael Roth, 2017/03/20
- [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