diff --git a/SOURCES/libvirt-qemu-fix-up-permissions-for-pre-created-UNIX-sockets.patch b/SOURCES/libvirt-qemu-fix-up-permissions-for-pre-created-UNIX-sockets.patch new file mode 100644 index 0000000..29c60fd --- /dev/null +++ b/SOURCES/libvirt-qemu-fix-up-permissions-for-pre-created-UNIX-sockets.patch @@ -0,0 +1,50 @@ +From cebb6519a3a4b65bf89d7f5ea7bf390f2303f5ee Mon Sep 17 00:00:00 2001 +Message-Id: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Wed, 3 Oct 2018 16:58:18 +0200 +Subject: [PATCH] qemu: fix up permissions for pre-created UNIX sockets +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +My commit d6b8838 fixed the uid:gid for the pre-created UNIX sockets +but did not account for the different umask of libvirtd and QEMU. +Since commit 0e1a1a8c we set umask to '0002' for the QEMU process. +Manually tune-up the permissions to match what we would have gotten +if QEMU had created the socket. + +https://bugzilla.redhat.com/show_bug.cgi?id=1633389 + +Signed-off-by: Ján Tomko +Reviewed-by: Jiri Denemark +(cherry picked from commit 8ba65c4d95712b54362fd81c34bae99f51d45a0b) +Signed-off-by: Ján Tomko + +RHEL 7.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=1635228 +RHEL 8.0: https://bugzilla.redhat.com/show_bug.cgi?id=1634775 + +Reviewed-by: Erik Skultety +--- + src/qemu/qemu_command.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index f2b64ed720..98b554627e 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -4933,6 +4933,12 @@ qemuOpenChrChardevUNIXSocket(const virDomainChrSourceDef *dev) + goto error; + } + ++ /* We run QEMU with umask 0002. Compensate for the umask ++ * libvirtd might be running under to get the same permission ++ * QEMU would have. */ ++ if (virFileUpdatePerm(dev->data.nix.path, 0002, 0664) < 0) ++ goto error; ++ + return fd; + + error: +-- +2.19.0 + diff --git a/SOURCES/libvirt-security-dac-also-label-listen-UNIX-sockets.patch b/SOURCES/libvirt-security-dac-also-label-listen-UNIX-sockets.patch new file mode 100644 index 0000000..bbd9d0e --- /dev/null +++ b/SOURCES/libvirt-security-dac-also-label-listen-UNIX-sockets.patch @@ -0,0 +1,65 @@ +From f019023539b64742e8f1ebc38ea26a204fa0a45c Mon Sep 17 00:00:00 2001 +Message-Id: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 2 Oct 2018 14:00:41 +0200 +Subject: [PATCH] security: dac: also label listen UNIX sockets +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We switched to opening mode='bind' sockets ourselves: +commit 30fb2276d88b275dc2aad6ddd28c100d944b59a5 + qemu: support passing pre-opened UNIX socket listen FD +in v4.5.0-rc1~251 + +Then fixed qemuBuildChrChardevStr to change libvirtd's label +while creating the socket: +commit b0c6300fc42bbc3e5eb0b236392f7344581c5810 + qemu: ensure FDs passed to QEMU for chardevs have correct SELinux labels +v4.5.0-rc1~52 + +Also add labeling of these sockets to the DAC driver. +Instead of duplicating the logic which decides whether libvirt should +pre-create the socket, assume an existing path meaning that it was created +by libvirt. + +https://bugzilla.redhat.com/show_bug.cgi?id=1633389 + +Signed-off-by: Ján Tomko +Reviewed-by: Erik Skultety +(cherry picked from commit d6b8838dd83697f721fe0706068df765148154de) +Signed-off-by: Ján Tomko + +RHEL 8.0: https://bugzilla.redhat.com/show_bug.cgi?id=1634775 +RHEL 7.6: https://bugzilla.redhat.com/show_bug.cgi?id=1635228 + +Conflicts: src/security/security_dac.c + commit 3ac7793ad1ae0f4dc7b7ddbcfd182d5ff0b45538 + security_dac: Pass virSecurityManagerPtr to virSecurityDACSetOwnership + is not backported +Reviewed-by: Jiri Denemark +--- + src/security/security_dac.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/security/security_dac.c b/src/security/security_dac.c +index 4b623dcf39..74c70dd092 100644 +--- a/src/security/security_dac.c ++++ b/src/security/security_dac.c +@@ -1248,7 +1248,12 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr, + break; + + case VIR_DOMAIN_CHR_TYPE_UNIX: +- if (!dev_source->data.nix.listen) { ++ if (!dev_source->data.nix.listen || ++ (dev_source->data.nix.path && ++ virFileExists(dev_source->data.nix.path))) { ++ /* Also label mode='bind' sockets if they exist, ++ * e.g. because they were created by libvirt ++ * and passed via FD */ + if (virSecurityDACSetOwnership(priv, NULL, + dev_source->data.nix.path, + user, group) < 0) +-- +2.19.0 + diff --git a/SOURCES/libvirt-virFileIsSharedFSType-Check-for-fuse.glusterfs-too.patch b/SOURCES/libvirt-virFileIsSharedFSType-Check-for-fuse.glusterfs-too.patch new file mode 100644 index 0000000..6049cf1 --- /dev/null +++ b/SOURCES/libvirt-virFileIsSharedFSType-Check-for-fuse.glusterfs-too.patch @@ -0,0 +1,128 @@ +From 945cc03b42ec947876cda10dff1bf76a446abbf1 Mon Sep 17 00:00:00 2001 +Message-Id: <945cc03b42ec947876cda10dff1bf76a446abbf1@dist-git> +From: Michal Privoznik +Date: Wed, 3 Oct 2018 17:04:13 +0200 +Subject: [PATCH] virFileIsSharedFSType: Check for fuse.glusterfs too + +RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1632711 +RHEL-8.0: https://bugzilla.redhat.com/show_bug.cgi?id=1634782 +RHEL-7.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=1635705 + +GlusterFS is typically safe when it comes to migration. It's a +network FS after all. However, it can be mounted via FUSE driver +they provide. If that is the case we fail to identify it and +think migration is not safe and require VIR_MIGRATE_UNSAFE flag. + +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +(cherry picked from commit 478da65fb46c866973886848ae17f1e16199a77d) +Signed-off-by: Michal Privoznik +--- + src/util/virfile.c | 77 ++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 75 insertions(+), 2 deletions(-) + +diff --git a/src/util/virfile.c b/src/util/virfile.c +index 378d03ecf0..c87e26bf5b 100644 +--- a/src/util/virfile.c ++++ b/src/util/virfile.c +@@ -3534,6 +3534,76 @@ int virFilePrintf(FILE *fp, const char *msg, ...) + # ifndef HUGETLBFS_MAGIC + # define HUGETLBFS_MAGIC 0x958458f6 + # endif ++# ifndef FUSE_SUPER_MAGIC ++# define FUSE_SUPER_MAGIC 0x65735546 ++# endif ++ ++# define PROC_MOUNTS "/proc/mounts" ++ ++static int ++virFileIsSharedFixFUSE(const char *path, ++ long *f_type) ++{ ++ char *dirpath = NULL; ++ const char **mounts = NULL; ++ size_t nmounts = 0; ++ char *p; ++ FILE *f = NULL; ++ struct mntent mb; ++ char mntbuf[1024]; ++ int ret = -1; ++ ++ if (VIR_STRDUP(dirpath, path) < 0) ++ return -1; ++ ++ if (!(f = setmntent(PROC_MOUNTS, "r"))) { ++ virReportSystemError(errno, ++ _("Unable to open %s"), ++ PROC_MOUNTS); ++ goto cleanup; ++ } ++ ++ while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) { ++ if (STRNEQ("fuse.glusterfs", mb.mnt_type)) ++ continue; ++ ++ if (VIR_APPEND_ELEMENT_COPY(mounts, nmounts, mb.mnt_dir) < 0) ++ goto cleanup; ++ } ++ ++ /* Add NULL sentinel so that this is a virStringList */ ++ if (VIR_REALLOC_N(mounts, nmounts + 1) < 0) ++ goto cleanup; ++ mounts[nmounts] = NULL; ++ ++ do { ++ if ((p = strrchr(dirpath, '/')) == NULL) { ++ virReportSystemError(EINVAL, ++ _("Invalid relative path '%s'"), path); ++ goto cleanup; ++ } ++ ++ if (p == dirpath) ++ *(p+1) = '\0'; ++ else ++ *p = '\0'; ++ ++ if (virStringListHasString(mounts, dirpath)) { ++ VIR_DEBUG("Found gluster FUSE mountpoint=%s for path=%s. " ++ "Fixing shared FS type", dirpath, path); ++ *f_type = GFS2_MAGIC; ++ break; ++ } ++ } while (p != dirpath); ++ ++ ret = 0; ++ cleanup: ++ endmntent(f); ++ VIR_FREE(mounts); ++ VIR_FREE(dirpath); ++ return ret; ++} ++ + + int + virFileIsSharedFSType(const char *path, +@@ -3581,6 +3651,11 @@ virFileIsSharedFSType(const char *path, + return -1; + } + ++ if (sb.f_type == FUSE_SUPER_MAGIC) { ++ VIR_DEBUG("Found FUSE mount for path=%s. Trying to fix it", path); ++ virFileIsSharedFixFUSE(path, (long *) &sb.f_type); ++ } ++ + VIR_DEBUG("Check if path %s with FS magic %lld is shared", + path, (long long int)sb.f_type); + +@@ -3673,8 +3748,6 @@ virFileGetDefaultHugepageSize(unsigned long long *size) + return ret; + } + +-# define PROC_MOUNTS "/proc/mounts" +- + int + virFileFindHugeTLBFS(virHugeTLBFSPtr *ret_fs, + size_t *ret_nfs) +-- +2.19.0 + diff --git a/SOURCES/libvirt-virFileIsSharedFSType-Detect-direct-mount-points.patch b/SOURCES/libvirt-virFileIsSharedFSType-Detect-direct-mount-points.patch new file mode 100644 index 0000000..676bba3 --- /dev/null +++ b/SOURCES/libvirt-virFileIsSharedFSType-Detect-direct-mount-points.patch @@ -0,0 +1,80 @@ +From 691b33e397a7bd726160bc74202c8d0fdd944892 Mon Sep 17 00:00:00 2001 +Message-Id: <691b33e397a7bd726160bc74202c8d0fdd944892@dist-git> +From: Michal Privoznik +Date: Wed, 10 Oct 2018 17:25:55 +0200 +Subject: [PATCH] virFileIsSharedFSType: Detect direct mount points + +RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1632711 +RHEL-8.0: https://bugzilla.redhat.com/show_bug.cgi?id=1634782 +RHEL-7.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=1635705 + +If the given path is already a mount point (e.g. a bind mount of +a file, or simply a direct mount point of a FS), then our code +fails to detect that because the first thing it does is cutting +off part after last slash '/'. + +Conflicts: + src/util/virfile.c - VIR_AUTOFREE() stuff + +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +(cherry picked from commit 98ca1d52a2a871e1c068504450b4dc15db063ef4) +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +--- + src/util/virfile.c | 9 +++++---- + tests/virfiletest.c | 3 +-- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/util/virfile.c b/src/util/virfile.c +index 46466ed136..05ecf7bf21 100644 +--- a/src/util/virfile.c ++++ b/src/util/virfile.c +@@ -3609,7 +3609,8 @@ int + virFileIsSharedFSType(const char *path, + int fstypes) + { +- char *dirpath, *p; ++ char *dirpath; ++ char *p = NULL; + struct statfs sb; + int statfs_ret; + long long f_type = 0; +@@ -3617,8 +3618,9 @@ virFileIsSharedFSType(const char *path, + if (VIR_STRDUP(dirpath, path) < 0) + return -1; + +- do { ++ statfs_ret = statfs(dirpath, &sb); + ++ while ((statfs_ret < 0) && (p != dirpath)) { + /* Try less and less of the path until we get to a + * directory we can stat. Even if we don't have 'x' + * permission on any directory in the path on the NFS +@@ -3640,8 +3642,7 @@ virFileIsSharedFSType(const char *path, + *p = '\0'; + + statfs_ret = statfs(dirpath, &sb); +- +- } while ((statfs_ret < 0) && (p != dirpath)); ++ } + + VIR_FREE(dirpath); + +diff --git a/tests/virfiletest.c b/tests/virfiletest.c +index 85f22063fe..80ea34bfa4 100644 +--- a/tests/virfiletest.c ++++ b/tests/virfiletest.c +@@ -454,8 +454,7 @@ mymain(void) + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts1.txt", "/boot/vmlinuz", false); + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts2.txt", "/run/user/501/gvfs/some/file", false); + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/file", true); +- /* TODO Detect bind mounts */ +- DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/blah", true); ++ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/blah", false); + + return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS; + } +-- +2.19.1 + diff --git a/SOURCES/libvirt-virfile-Rework-virFileIsSharedFixFUSE.patch b/SOURCES/libvirt-virfile-Rework-virFileIsSharedFixFUSE.patch new file mode 100644 index 0000000..7e48516 --- /dev/null +++ b/SOURCES/libvirt-virfile-Rework-virFileIsSharedFixFUSE.patch @@ -0,0 +1,151 @@ +From 872bff1f3e49219389ed57bc2fbff8614b5f9be9 Mon Sep 17 00:00:00 2001 +Message-Id: <872bff1f3e49219389ed57bc2fbff8614b5f9be9@dist-git> +From: Michal Privoznik +Date: Wed, 10 Oct 2018 17:25:56 +0200 +Subject: [PATCH] virfile: Rework virFileIsSharedFixFUSE + +RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1632711 +RHEL-8.0: https://bugzilla.redhat.com/show_bug.cgi?id=1634782 +RHEL-7.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=1635705 + +There are couple of things wrong with the current implementation. +The first one is that in the first loop the code tries to build a +list of fuse.glusterfs mount points. Well, since the strings are +allocated in a temporary buffer and are not duplicated this +results in wrong decision made later in the code. + +The second problem is that the code does not take into account +subtree mounts. For instance, if there's a fuse.gluster mounted +at /some/path and another FS mounted at /some/path/subdir the +code would not recognize this subdir mount. + +Reported-by: Han Han +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +(cherry picked from commit 1dbf6222dd5e1fedcbe335fc0852ef66e7a92901) +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +--- + src/util/virfile.c | 61 ++++++++++++++--------------------- + tests/virfiledata/mounts3.txt | 2 ++ + tests/virfiletest.c | 2 ++ + 3 files changed, 29 insertions(+), 36 deletions(-) + +diff --git a/src/util/virfile.c b/src/util/virfile.c +index 05ecf7bf21..e1dee7633a 100644 +--- a/src/util/virfile.c ++++ b/src/util/virfile.c +@@ -3544,18 +3544,14 @@ static int + virFileIsSharedFixFUSE(const char *path, + long long *f_type) + { +- char *dirpath = NULL; +- const char **mounts = NULL; +- size_t nmounts = 0; +- char *p; + FILE *f = NULL; + struct mntent mb; + char mntbuf[1024]; ++ char *mntDir = NULL; ++ char *mntType = NULL; ++ size_t maxMatching = 0; + int ret = -1; + +- if (VIR_STRDUP(dirpath, path) < 0) +- return -1; +- + if (!(f = setmntent(PROC_MOUNTS, "r"))) { + virReportSystemError(errno, + _("Unable to open %s"), +@@ -3564,43 +3560,36 @@ virFileIsSharedFixFUSE(const char *path, + } + + while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) { +- if (STRNEQ("fuse.glusterfs", mb.mnt_type)) ++ const char *p; ++ size_t len = strlen(mb.mnt_dir); ++ ++ if (!(p = STRSKIP(path, mb.mnt_dir))) + continue; + +- if (VIR_APPEND_ELEMENT_COPY(mounts, nmounts, mb.mnt_dir) < 0) +- goto cleanup; ++ if (*(p - 1) != '/' && *p != '/' && *p != '\0') ++ continue; ++ ++ if (len > maxMatching) { ++ maxMatching = len; ++ VIR_FREE(mntType); ++ VIR_FREE(mntDir); ++ if (VIR_STRDUP(mntDir, mb.mnt_dir) < 0 || ++ VIR_STRDUP(mntType, mb.mnt_type) < 0) ++ goto cleanup; ++ } + } + +- /* Add NULL sentinel so that this is a virStringList */ +- if (VIR_REALLOC_N(mounts, nmounts + 1) < 0) +- goto cleanup; +- mounts[nmounts] = NULL; +- +- do { +- if ((p = strrchr(dirpath, '/')) == NULL) { +- virReportSystemError(EINVAL, +- _("Invalid relative path '%s'"), path); +- goto cleanup; +- } +- +- if (p == dirpath) +- *(p+1) = '\0'; +- else +- *p = '\0'; +- +- if (virStringListHasString(mounts, dirpath)) { +- VIR_DEBUG("Found gluster FUSE mountpoint=%s for path=%s. " +- "Fixing shared FS type", dirpath, path); +- *f_type = GFS2_MAGIC; +- break; +- } +- } while (p != dirpath); ++ if (STREQ_NULLABLE(mntType, "fuse.glusterfs")) { ++ VIR_DEBUG("Found gluster FUSE mountpoint=%s for path=%s. " ++ "Fixing shared FS type", mntDir, path); ++ *f_type = GFS2_MAGIC; ++ } + + ret = 0; + cleanup: ++ VIR_FREE(mntType); ++ VIR_FREE(mntDir); + endmntent(f); +- VIR_FREE(mounts); +- VIR_FREE(dirpath); + return ret; + } + +diff --git a/tests/virfiledata/mounts3.txt b/tests/virfiledata/mounts3.txt +index 226f67dc00..134c6e8f81 100644 +--- a/tests/virfiledata/mounts3.txt ++++ b/tests/virfiledata/mounts3.txt +@@ -31,3 +31,5 @@ hugetlbfs /hugepages2M hugetlbfs rw,relatime,mode=1777,pagesize=2M 0 0 + none /run/user/1000 tmpfs rw,relatime,mode=700,uid=1000 0 0 + host:/nfs /nfs nfs4 rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp6,timeo=600,retrans=2,sec=sys,clientaddr=::,local_lock=none,addr=:: 0 0 + dev /nfs/blah devtmpfs rw,nosuid,relatime,size=10240k,nr_inodes=4093060,mode=755 0 0 ++host:/gv0 /gluster fuse.glusterfs rw 0 0 ++root@host:/tmp/mkdir /gluster/sshfs fuse.sshfs rw 0 0 +diff --git a/tests/virfiletest.c b/tests/virfiletest.c +index 80ea34bfa4..be4dbf8910 100644 +--- a/tests/virfiletest.c ++++ b/tests/virfiletest.c +@@ -455,6 +455,8 @@ mymain(void) + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts2.txt", "/run/user/501/gvfs/some/file", false); + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/file", true); + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/blah", false); ++ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/file", true); ++ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/sshfs/file", false); + + return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS; + } +-- +2.19.1 + diff --git a/SOURCES/libvirt-virfile-fix-cast-align-error.patch b/SOURCES/libvirt-virfile-fix-cast-align-error.patch new file mode 100644 index 0000000..9c78b0f --- /dev/null +++ b/SOURCES/libvirt-virfile-fix-cast-align-error.patch @@ -0,0 +1,95 @@ +From 5b47ca781fddf2704b55370acf7cc369ae049c64 Mon Sep 17 00:00:00 2001 +Message-Id: <5b47ca781fddf2704b55370acf7cc369ae049c64@dist-git> +From: Marc Hartmayer +Date: Wed, 10 Oct 2018 17:25:52 +0200 +Subject: [PATCH] virfile: fix cast-align error + +RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1632711 +RHEL-8.0: https://bugzilla.redhat.com/show_bug.cgi?id=1634782 +RHEL-7.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=1635705 + +On s390x the struct member f_type of statsfs is hard coded to 'unsigned +int'. Change virFileIsSharedFixFUSE() to take a 'long long int' and use +a temporary to avoid pointer-casting. + +This fixes the following error: +../../src/util/virfile.c:3578:38: error: cast increases required alignment of target type [-Werror=cast-align] + virFileIsSharedFixFUSE(path, (long *) &sb.f_type); + +Signed-off-by: Marc Hartmayer +Signed-off-by: Bjoern Walk +(cherry picked from commit 2b03534eeb2f3f41865538cd4c3e5d326260ad27) +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +--- + src/util/virfile.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/src/util/virfile.c b/src/util/virfile.c +index c87e26bf5b..46466ed136 100644 +--- a/src/util/virfile.c ++++ b/src/util/virfile.c +@@ -3542,7 +3542,7 @@ int virFilePrintf(FILE *fp, const char *msg, ...) + + static int + virFileIsSharedFixFUSE(const char *path, +- long *f_type) ++ long long *f_type) + { + char *dirpath = NULL; + const char **mounts = NULL; +@@ -3612,6 +3612,7 @@ virFileIsSharedFSType(const char *path, + char *dirpath, *p; + struct statfs sb; + int statfs_ret; ++ long long f_type = 0; + + if (VIR_STRDUP(dirpath, path) < 0) + return -1; +@@ -3651,32 +3652,34 @@ virFileIsSharedFSType(const char *path, + return -1; + } + +- if (sb.f_type == FUSE_SUPER_MAGIC) { ++ f_type = sb.f_type; ++ ++ if (f_type == FUSE_SUPER_MAGIC) { + VIR_DEBUG("Found FUSE mount for path=%s. Trying to fix it", path); +- virFileIsSharedFixFUSE(path, (long *) &sb.f_type); ++ virFileIsSharedFixFUSE(path, &f_type); + } + + VIR_DEBUG("Check if path %s with FS magic %lld is shared", +- path, (long long int)sb.f_type); ++ path, f_type); + + if ((fstypes & VIR_FILE_SHFS_NFS) && +- (sb.f_type == NFS_SUPER_MAGIC)) ++ (f_type == NFS_SUPER_MAGIC)) + return 1; + + if ((fstypes & VIR_FILE_SHFS_GFS2) && +- (sb.f_type == GFS2_MAGIC)) ++ (f_type == GFS2_MAGIC)) + return 1; + if ((fstypes & VIR_FILE_SHFS_OCFS) && +- (sb.f_type == OCFS2_SUPER_MAGIC)) ++ (f_type == OCFS2_SUPER_MAGIC)) + return 1; + if ((fstypes & VIR_FILE_SHFS_AFS) && +- (sb.f_type == AFS_FS_MAGIC)) ++ (f_type == AFS_FS_MAGIC)) + return 1; + if ((fstypes & VIR_FILE_SHFS_SMB) && +- (sb.f_type == SMB_SUPER_MAGIC)) ++ (f_type == SMB_SUPER_MAGIC)) + return 1; + if ((fstypes & VIR_FILE_SHFS_CIFS) && +- (sb.f_type == CIFS_SUPER_MAGIC)) ++ (f_type == CIFS_SUPER_MAGIC)) + return 1; + + return 0; +-- +2.19.1 + diff --git a/SOURCES/libvirt-virfiletest-Fix-test-name-prefix-for-virFileInData-test.patch b/SOURCES/libvirt-virfiletest-Fix-test-name-prefix-for-virFileInData-test.patch new file mode 100644 index 0000000..aac2b72 --- /dev/null +++ b/SOURCES/libvirt-virfiletest-Fix-test-name-prefix-for-virFileInData-test.patch @@ -0,0 +1,37 @@ +From afbd3adabf31cbf870c7a3787af6466cfe9cb0d1 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Wed, 10 Oct 2018 17:25:53 +0200 +Subject: [PATCH] virfiletest: Fix test name prefix for virFileInData test + +RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1632711 +RHEL-8.0: https://bugzilla.redhat.com/show_bug.cgi?id=1634782 +RHEL-7.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=1635705 + +Because of lacking virTestCounterReset() call, the old test cases +name was preserved. + +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +(cherry picked from commit 6814ac678e07ea3f2f8351eb75c82af9ad9d727f) +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +--- + tests/virfiletest.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/virfiletest.c b/tests/virfiletest.c +index a15495e9e8..790911cacb 100644 +--- a/tests/virfiletest.c ++++ b/tests/virfiletest.c +@@ -389,6 +389,7 @@ mymain(void) + } while (0) + + if (holesSupported()) { ++ virTestCounterReset("testFileInData "); + DO_TEST_IN_DATA(true, 4, 4, 4); + DO_TEST_IN_DATA(false, 4, 4, 4); + DO_TEST_IN_DATA(true, 8, 8, 8); +-- +2.19.1 + diff --git a/SOURCES/libvirt-virfiletst-Test-virFileIsSharedFS.patch b/SOURCES/libvirt-virfiletst-Test-virFileIsSharedFS.patch new file mode 100644 index 0000000..150767b --- /dev/null +++ b/SOURCES/libvirt-virfiletst-Test-virFileIsSharedFS.patch @@ -0,0 +1,358 @@ +From 4a8593827fa1440e741b685e9ba3f0c7e3b17e99 Mon Sep 17 00:00:00 2001 +Message-Id: <4a8593827fa1440e741b685e9ba3f0c7e3b17e99@dist-git> +From: Michal Privoznik +Date: Wed, 10 Oct 2018 17:25:54 +0200 +Subject: [PATCH] virfiletst: Test virFileIsSharedFS + +RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1632711 +RHEL-8.0: https://bugzilla.redhat.com/show_bug.cgi?id=1634782 +RHEL-7.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=1635705 + +Introduce some basic test cases for virFileIsSharedFS(). More +will be added later. In order to achieve desired result, mocks +for setmntent() and statfs() need to be invented because the +first thing that virFileIsSharedFS() does is calling the latter. +If it finds a FUSE mount it'll call the former. + +The mock might look a bit complicated, but in fact it's quite +simple. The test sets LIBVIRT_MTAB env variable to hold the +absolute path to a file containing mount table. Then, statfs() +returns matching FS it finds, and setmntent() is there just to +replace /proc/mounts with the file the test wants to load. + +Adding this test also exposed a bug we have - because we assume +the given path points to a file we cut off what we assume is a +file name to obtain directory path and only then we call +statfs(). This is buggy because the passed path could be already +a mount point. + +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +(cherry picked from commit a7b4eb7d261255d70d90047ae34e8eea849053f2) +Signed-off-by: Michal Privoznik +Reviewed-by: Jiri Denemark +--- + tests/Makefile.am | 7 +- + tests/virfiledata/mounts3.txt | 33 ++++++++ + tests/virfilemock.c | 154 ++++++++++++++++++++++++++++++++++ + tests/virfiletest.c | 62 +++++++++++++- + 4 files changed, 254 insertions(+), 2 deletions(-) + create mode 100644 tests/virfiledata/mounts3.txt + create mode 100644 tests/virfilemock.c + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index f5872fa42b..a4ebed489a 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -242,6 +242,7 @@ test_libraries += virusbmock.la \ + virnetdevbandwidthmock.la \ + virnumamock.la \ + virtestmock.la \ ++ virfilemock.la \ + $(NULL) + endif WITH_LINUX + +@@ -1163,9 +1164,13 @@ virresctrltest_SOURCES = \ + virresctrltest.c testutils.h testutils.c virfilewrapper.h virfilewrapper.c + virresctrltest_LDADD = $(LDADDS) + ++virfilemock_la_SOURCES = \ ++ virfilemock.c ++virfilemock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS) ++virfilemock_la_LIBADD = $(MOCKLIBS_LIBS) + else ! WITH_LINUX + EXTRA_DIST += vircaps2xmltest.c virnumamock.c virfilewrapper.c \ +- virfilewrapper.h virresctrltest.c ++ virfilewrapper.h virresctrltest.c virfilemock.c + endif ! WITH_LINUX + + if WITH_NSS +diff --git a/tests/virfiledata/mounts3.txt b/tests/virfiledata/mounts3.txt +new file mode 100644 +index 0000000000..226f67dc00 +--- /dev/null ++++ b/tests/virfiledata/mounts3.txt +@@ -0,0 +1,33 @@ ++/dev/root / xfs rw,noatime,attr2,inode64,noquota 0 0 ++proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 ++tmpfs /run tmpfs rw,nodev,relatime,size=3281436k,mode=755 0 0 ++sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0 ++dev /dev devtmpfs rw,nosuid,relatime,size=10240k,nr_inodes=4093060,mode=755 0 0 ++securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0 ++debugfs /sys/kernel/debug debugfs rw,nosuid,nodev,noexec,relatime 0 0 ++mqueue /dev/mqueue mqueue rw,nosuid,nodev,noexec,relatime 0 0 ++configfs /sys/kernel/config configfs rw,nosuid,nodev,noexec,relatime 0 0 ++devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0 ++fusectl /sys/fs/fuse/connections fusectl rw,nosuid,nodev,noexec,relatime 0 0 ++shm /dev/shm tmpfs rw,nosuid,nodev,noexec,relatime 0 0 ++cgroup_root /sys/fs/cgroup tmpfs rw,nosuid,nodev,noexec,relatime,size=10240k,mode=755 0 0 ++openrc /sys/fs/cgroup/openrc cgroup rw,nosuid,nodev,noexec,relatime,release_agent=/lib/rc/sh/cgroup-release-agent.sh,name=openrc 0 0 ++none /sys/fs/cgroup/unified cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate 0 0 ++cpuset /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0 ++cpu /sys/fs/cgroup/cpu cgroup rw,nosuid,nodev,noexec,relatime,cpu 0 0 ++cpuacct /sys/fs/cgroup/cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct 0 0 ++blkio /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0 ++memory /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0 ++devices /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0 ++freezer /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0 ++net_cls /sys/fs/cgroup/net_cls cgroup rw,nosuid,nodev,noexec,relatime,net_cls 0 0 ++perf_event /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0 ++net_prio /sys/fs/cgroup/net_prio cgroup rw,nosuid,nodev,noexec,relatime,net_prio 0 0 ++hugetlb /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0 ++pids /sys/fs/cgroup/pids cgroup rw,nosuid,nodev,noexec,relatime,pids 0 0 ++rdma /sys/fs/cgroup/rdma cgroup rw,nosuid,nodev,noexec,relatime,rdma 0 0 ++binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,nosuid,nodev,noexec,relatime 0 0 ++hugetlbfs /hugepages2M hugetlbfs rw,relatime,mode=1777,pagesize=2M 0 0 ++none /run/user/1000 tmpfs rw,relatime,mode=700,uid=1000 0 0 ++host:/nfs /nfs nfs4 rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp6,timeo=600,retrans=2,sec=sys,clientaddr=::,local_lock=none,addr=:: 0 0 ++dev /nfs/blah devtmpfs rw,nosuid,relatime,size=10240k,nr_inodes=4093060,mode=755 0 0 +diff --git a/tests/virfilemock.c b/tests/virfilemock.c +new file mode 100644 +index 0000000000..822c757380 +--- /dev/null ++++ b/tests/virfilemock.c +@@ -0,0 +1,154 @@ ++/* ++ * Copyright (C) 2018 Red Hat, Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ * ++ * Author: Michal Privoznik ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#if HAVE_LINUX_MAGIC_H ++# include ++#endif ++ ++#include "virmock.h" ++ ++#define VIR_FROM_THIS VIR_FROM_NONE ++ ++static FILE *(*real_setmntent)(const char *filename, const char *type); ++static int (*real_statfs)(const char *path, struct statfs *buf); ++ ++ ++static void ++init_syms(void) ++{ ++ if (real_setmntent) ++ return; ++ ++ VIR_MOCK_REAL_INIT(setmntent); ++ VIR_MOCK_REAL_INIT(statfs); ++} ++ ++ ++FILE * ++setmntent(const char *filename, const char *type) ++{ ++ const char *mtab; ++ ++ init_syms(); ++ ++ if ((mtab = getenv("LIBVIRT_MTAB"))) ++ filename = mtab; ++ ++ return real_setmntent(filename, type); ++} ++ ++ ++#ifndef NFS_SUPER_MAGIC ++# define NFS_SUPER_MAGIC 0x6969 ++#endif ++#ifndef OCFS2_SUPER_MAGIC ++# define OCFS2_SUPER_MAGIC 0x7461636f ++#endif ++#ifndef GFS2_MAGIC ++# define GFS2_MAGIC 0x01161970 ++#endif ++#ifndef AFS_FS_MAGIC ++# define AFS_FS_MAGIC 0x6B414653 ++#endif ++#ifndef SMB_SUPER_MAGIC ++# define SMB_SUPER_MAGIC 0x517B ++#endif ++#ifndef CIFS_SUPER_MAGIC ++# define CIFS_SUPER_MAGIC 0xFF534D42 ++#endif ++#ifndef HUGETLBFS_MAGIC ++# define HUGETLBFS_MAGIC 0x958458f6 ++#endif ++#ifndef FUSE_SUPER_MAGIC ++# define FUSE_SUPER_MAGIC 0x65735546 ++#endif ++ ++ ++static int ++statfs_mock(const char *mtab, ++ const char *path, ++ struct statfs *buf) ++{ ++ FILE *f; ++ struct mntent mb; ++ char mntbuf[1024]; ++ int ret = -1; ++ ++ if (!(f = real_setmntent(mtab, "r"))) { ++ fprintf(stderr, "Unable to open %s", mtab); ++ return -1; ++ } ++ ++ while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) { ++ int ftype; ++ ++ if (STRNEQ(mb.mnt_dir, path)) ++ continue; ++ ++ if (STREQ(mb.mnt_type, "nfs") || ++ STREQ(mb.mnt_type, "nfs4")) { ++ ftype = NFS_SUPER_MAGIC; ++ } else if (STREQ(mb.mnt_type, "gfs2")|| ++ STREQ(mb.mnt_type, "gfs2meta")) { ++ ftype = GFS2_MAGIC; ++ } else if (STREQ(mb.mnt_type, "ocfs2")) { ++ ftype = OCFS2_SUPER_MAGIC; ++ } else if (STREQ(mb.mnt_type, "afs")) { ++ ftype = AFS_FS_MAGIC; ++ } else if (STREQ(mb.mnt_type, "smb3")) { ++ ftype = SMB_SUPER_MAGIC; ++ } else if (STREQ(mb.mnt_type, "cifs")) { ++ ftype = CIFS_SUPER_MAGIC; ++ } else if (STRPREFIX(mb.mnt_type, "fuse")) { ++ ftype = FUSE_SUPER_MAGIC; ++ } else { ++ /* Everything else is EXT4. We don't care really for other paths. */ ++ ftype = EXT4_SUPER_MAGIC; ++ } ++ ++ memset(buf, 0, sizeof(*buf)); ++ /* We only care about f_type so far. */ ++ buf->f_type = ftype; ++ ret = 0; ++ break; ++ } ++ ++ endmntent(f); ++ return ret; ++} ++ ++ ++int ++statfs(const char *path, struct statfs *buf) ++{ ++ const char *mtab; ++ ++ init_syms(); ++ ++ if ((mtab = getenv("LIBVIRT_MTAB"))) ++ return statfs_mock(mtab, path, buf); ++ ++ return real_statfs(path, buf); ++} +diff --git a/tests/virfiletest.c b/tests/virfiletest.c +index 790911cacb..85f22063fe 100644 +--- a/tests/virfiletest.c ++++ b/tests/virfiletest.c +@@ -31,6 +31,7 @@ + # include + #endif + ++#define VIR_FROM_THIS VIR_FROM_NONE + + #if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R + static int testFileCheckMounts(const char *prefix, +@@ -310,6 +311,48 @@ testFileInData(const void *opaque) + } + + ++struct testFileIsSharedFSType { ++ const char *mtabFile; ++ const char *filename; ++ const bool expected; ++}; ++ ++static int ++testFileIsSharedFSType(const void *opaque ATTRIBUTE_UNUSED) ++{ ++#ifndef __linux__ ++ return EXIT_AM_SKIP; ++#else ++ const struct testFileIsSharedFSType *data = opaque; ++ char *mtabFile = NULL; ++ bool actual; ++ int ret = -1; ++ ++ if (virAsprintf(&mtabFile, abs_srcdir "/virfiledata/%s", data->mtabFile) < 0) ++ return -1; ++ ++ if (setenv("LIBVIRT_MTAB", mtabFile, 1) < 0) { ++ fprintf(stderr, "Unable to set env variable\n"); ++ goto cleanup; ++ } ++ ++ actual = virFileIsSharedFS(data->filename); ++ ++ if (actual != data->expected) { ++ fprintf(stderr, "Unexpected FS type. Expected %d got %d\n", ++ data->expected, actual); ++ goto cleanup; ++ } ++ ++ ret = 0; ++ cleanup: ++ VIR_FREE(mtabFile); ++ unsetenv("LIBVIRT_MTAB"); ++ return ret; ++#endif ++} ++ ++ + static int + mymain(void) + { +@@ -397,7 +440,24 @@ mymain(void) + DO_TEST_IN_DATA(true, 8, 16, 32, 64, 128, 256, 512); + DO_TEST_IN_DATA(false, 8, 16, 32, 64, 128, 256, 512); + } ++ ++#define DO_TEST_FILE_IS_SHARED_FS_TYPE(mtab, file, exp) \ ++ do { \ ++ struct testFileIsSharedFSType data = { \ ++ .mtabFile = mtab, .filename = file, .expected = exp \ ++ }; \ ++ if (virTestRun(virTestCounterNext(), testFileIsSharedFSType, &data) < 0) \ ++ ret = -1; \ ++ } while (0) ++ ++ virTestCounterReset("testFileIsSharedFSType "); ++ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts1.txt", "/boot/vmlinuz", false); ++ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts2.txt", "/run/user/501/gvfs/some/file", false); ++ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/file", true); ++ /* TODO Detect bind mounts */ ++ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/blah", true); ++ + return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS; + } + +-VIR_TEST_MAIN(mymain) ++VIR_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virfilemock.so") +-- +2.19.1 + diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec index a88d53a..a8843b7 100644 --- a/SPECS/libvirt.spec +++ b/SPECS/libvirt.spec @@ -253,7 +253,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 4.5.0 -Release: 10%{?dist}%{?extra_release} +Release: 10%{?dist}.2%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -366,6 +366,14 @@ Patch100: libvirt-virDomainDefCompatibleDevice-Relax-alias-change-check.patch Patch101: libvirt-virDomainDetachDeviceFlags-Clarify-update-semantics.patch Patch102: libvirt-virDomainNetDefCheckABIStability-Check-for-MTU-change-too.patch Patch103: libvirt-conf-correct-false-boot-order-error-during-domain-parse.patch +Patch104: libvirt-security-dac-also-label-listen-UNIX-sockets.patch +Patch105: libvirt-qemu-fix-up-permissions-for-pre-created-UNIX-sockets.patch +Patch106: libvirt-virFileIsSharedFSType-Check-for-fuse.glusterfs-too.patch +Patch107: libvirt-virfile-fix-cast-align-error.patch +Patch108: libvirt-virfiletest-Fix-test-name-prefix-for-virFileInData-test.patch +Patch109: libvirt-virfiletst-Test-virFileIsSharedFS.patch +Patch110: libvirt-virFileIsSharedFSType-Detect-direct-mount-points.patch +Patch111: libvirt-virfile-Rework-virFileIsSharedFixFUSE.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2265,6 +2273,18 @@ exit 0 %changelog +* Wed Oct 10 2018 Jiri Denemark - 4.5.0-10.el7_6.2 +- virfile: fix cast-align error (rhbz#1635705) +- virfiletest: Fix test name prefix for virFileInData test (rhbz#1635705) +- virfiletst: Test virFileIsSharedFS (rhbz#1635705) +- virFileIsSharedFSType: Detect direct mount points (rhbz#1635705) +- virfile: Rework virFileIsSharedFixFUSE (rhbz#1635705) + +* Mon Oct 8 2018 Jiri Denemark - 4.5.0-10.el7_6.1 +- security: dac: also label listen UNIX sockets (rhbz#1635228) +- qemu: fix up permissions for pre-created UNIX sockets (rhbz#1635228) +- virFileIsSharedFSType: Check for fuse.glusterfs too (rhbz#1635705) + * Tue Sep 18 2018 Jiri Denemark - 4.5.0-10 - conf: correct false boot order error during domain parse (rhbz#1601318)