diff mbox

[v2,2/2] 9pfs: fix vulnerability in openat_dir() and local_unlinkat_common()

Message ID 148878898250.4635.16941960568938577780.stgit@bahia
State New
Headers show

Commit Message

Greg Kurz March 6, 2017, 8:29 a.m. UTC
We should pass O_NOFOLLOW otherwise openat() will follow symlinks and make
QEMU vulnerable.

While here, we also fix local_unlinkat_common() to use openat_dir() for
the same reasons (it was a leftover in the original patchset actually).

This fixes CVE-2016-9602.

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
--
v2: - keep O_PATH (Eric Blake)
---
 hw/9pfs/9p-local.c |    2 +-
 hw/9pfs/9p-util.h  |    3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

Comments

Eric Blake March 6, 2017, 4:18 p.m. UTC | #1
On 03/06/2017 02:29 AM, Greg Kurz wrote:
> We should pass O_NOFOLLOW otherwise openat() will follow symlinks and make
> QEMU vulnerable.
> 
> While here, we also fix local_unlinkat_common() to use openat_dir() for
> the same reasons (it was a leftover in the original patchset actually).
> 
> This fixes CVE-2016-9602.
> 
> Signed-off-by: Greg Kurz <groug@kaod.org>
> Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
> --
> v2: - keep O_PATH (Eric Blake)

Reviewed-by: Eric Blake <eblake@redhat.com>
diff mbox

Patch

diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 0ca4c94ee4a8..45e9a1f9b0ca 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -960,7 +960,7 @@  static int local_unlinkat_common(FsContext *ctx, int dirfd, const char *name,
         if (flags == AT_REMOVEDIR) {
             int fd;
 
-            fd = openat(dirfd, name, O_RDONLY | O_DIRECTORY | O_PATH);
+            fd = openat_dir(dirfd, name);
             if (fd == -1) {
                 goto err_out;
             }
diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h
index cb7b2072d3ac..517027c52032 100644
--- a/hw/9pfs/9p-util.h
+++ b/hw/9pfs/9p-util.h
@@ -27,7 +27,8 @@  static inline int openat_dir(int dirfd, const char *name)
 #else
 #define OPENAT_DIR_O_PATH 0
 #endif
-    return openat(dirfd, name, O_DIRECTORY | O_RDONLY | OPENAT_DIR_O_PATH);
+    return openat(dirfd, name,
+                  O_DIRECTORY | O_RDONLY | O_NOFOLLOW | OPENAT_DIR_O_PATH);
 }
 
 static inline int openat_file(int dirfd, const char *name, int flags,