Commit d6780c82 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/gkurz/tags/fixes-for-2.9' into staging



Fixes issues that got merged with the latest pull request:
- missing O_NOFOLLOW flag for CVE-2016-960
- build break with older glibc that don't have O_PATH and AT_EMPTY_PATH
- various bugs reported by Coverity

# gpg: Signature made Mon 06 Mar 2017 17:51:29 GMT
# gpg:                using DSA key 0x02FC3AEB0101DBC2
# gpg: Good signature from "Greg Kurz <groug@kaod.org>"
# gpg:                 aka "Greg Kurz <groug@free.fr>"
# gpg:                 aka "Greg Kurz <gkurz@linux.vnet.ibm.com>"
# gpg:                 aka "Gregory Kurz (Groug) <groug@free.fr>"
# gpg:                 aka "[jpeg image of size 3330]"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 2BD4 3B44 535E C0A7 9894  DBA2 02FC 3AEB 0101 DBC2

* remotes/gkurz/tags/fixes-for-2.9:
  9pfs: fix vulnerability in openat_dir() and local_unlinkat_common()
  9pfs: fix O_PATH build break with older glibc versions
  9pfs: don't use AT_EMPTY_PATH in local_set_cred_passthrough()
  9pfs: fail local_statfs() earlier
  9pfs: fix fd leak in local_opendir()
  9pfs: fix bogus fd check in local_remove()

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 7dc3bc7a b003fc0d
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -349,7 +349,7 @@ static int local_set_cred_passthrough(FsContext *fs_ctx, int dirfd,
                                      const char *name, FsCred *credp)
{
    if (fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
                 AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH) < 0) {
                 AT_SYMLINK_NOFOLLOW) < 0) {
        /*
         * If we fail to change ownership and if we are
         * using security model none. Ignore the error
@@ -435,6 +435,7 @@ static int local_opendir(FsContext *ctx,

    stream = fdopendir(dirfd);
    if (!stream) {
        close(dirfd);
        return -1;
    }
    fs->dir.stream = stream;
@@ -959,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;
            }
@@ -1008,7 +1009,7 @@ static int local_remove(FsContext *ctx, const char *path)
    int err = -1;

    dirfd = local_opendir_nofollow(ctx, dirpath);
    if (dirfd) {
    if (dirfd == -1) {
        goto out;
    }

@@ -1052,6 +1053,9 @@ static int local_statfs(FsContext *s, V9fsPath *fs_path, struct statfs *stbuf)
    int fd, ret;

    fd = local_open_nofollow(s, fs_path->data, O_RDONLY, 0);
    if (fd == -1) {
        return -1;
    }
    ret = fstatfs(fd, stbuf);
    close_preserve_errno(fd);
    return ret;
+7 −1
Original line number Diff line number Diff line
@@ -22,7 +22,13 @@ 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);
#ifdef O_PATH
#define OPENAT_DIR_O_PATH O_PATH
#else
#define OPENAT_DIR_O_PATH 0
#endif
    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,