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
 -----BEGIN PGP SIGNATURE-----
 
 iEYEABECAAYFAli9oaEACgkQAvw66wEB28JOrACgkACey3usrIOcsOjObqKC8m1u
 9hEAnihQPzVEBBKoDuWylzU/scUg+7ho
 =8xHj
 -----END PGP SIGNATURE-----

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: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2017-03-07 09:09:53 +00:00
commit d6780c8221
2 changed files with 14 additions and 4 deletions

View File

@ -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;

View File

@ -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,