[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] 9pfs: fix vulnerability in openat_dir() and loc
From: |
Daniel P. Berrange |
Subject: |
Re: [Qemu-devel] [PATCH] 9pfs: fix vulnerability in openat_dir() and local_unlinkat_common() |
Date: |
Fri, 3 Mar 2017 17:28:58 +0000 |
User-agent: |
Mutt/1.7.1 (2016-10-04) |
On Fri, Mar 03, 2017 at 06:25:30PM +0100, Greg Kurz wrote:
> We should pass O_NOFOLLOW otherwise openat() will follow symlinks and make
> QEMU vulnerable.
>
> O_PATH was used as an optimization: the fd returned by openat_dir() is only
> passed to openat() actually, so we don't really need to reach the underlying
> filesystem.
>
> O_NOFOLLOW | O_PATH isn't an option: if name is a symlink, openat() will
> return a fd, forcing us to do some other syscall to detect we have a
> symlink. Also, O_PATH doesn't exist in glibc 2.13 and older.
>
> The only sane thing to do is hence to drop O_PATH, and only pass O_NOFOLLOW.
>
> 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 <address@hidden>
> ---
> hw/9pfs/9p-local.c | 2 +-
> hw/9pfs/9p-util.h | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
> index 5db7104334d6..e31309a29c58 100644
> --- a/hw/9pfs/9p-local.c
> +++ b/hw/9pfs/9p-local.c
> @@ -959,7 +959,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 091f3ce88e15..4001d1fd8398 100644
> --- a/hw/9pfs/9p-util.h
> +++ b/hw/9pfs/9p-util.h
> @@ -22,7 +22,7 @@ static inline void close_preserve_errno(int fd)
>
> static inline int openat_dir(int dirfd, const char *name)
> {
> - return openat(dirfd, name, O_DIRECTORY | O_RDONLY | O_PATH);
> + return openat(dirfd, name, O_DIRECTORY | O_RDONLY | O_NOFOLLOW);
> }
>
> static inline int openat_file(int dirfd, const char *name, int flags,
Reviewed-by: Daniel P. Berrange <address@hidden>
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|