acda74
From fd06fc3affcda0d7af1721c26915b8d87e0b2614 Mon Sep 17 00:00:00 2001
acda74
Message-Id: <fd06fc3affcda0d7af1721c26915b8d87e0b2614@dist-git>
acda74
From: Michal Privoznik <mprivozn@redhat.com>
acda74
Date: Tue, 7 Feb 2023 15:06:32 +0100
acda74
Subject: [PATCH] qemu_namespace: Deal with nested mounts when umount()-ing
acda74
 /dev
acda74
acda74
In one of recent commits (v9.0.0-rc1~106) I've made our QEMU
acda74
namespace code umount the original /dev. One of the reasons was
acda74
enhanced security, because previously we just mounted a tmpfs
acda74
over the original /dev. Thus a malicious QEMU could just
acda74
umount("/dev") and it would get to the original /dev with all
acda74
nodes.
acda74
acda74
Now, on some systems this introduced a regression:
acda74
acda74
   failed to umount devfs on /dev: Device or resource busy
acda74
acda74
But how this could be? We've moved all file systems mounted under
acda74
/dev to a temporary location. Or have we? As it turns out, not
acda74
quite. If there are two file systems mounted on the same target,
acda74
e.g. like this:
acda74
acda74
  mount -t tmpfs tmpfs /dev/shm/ && mount -t tmpfs tmpfs /dev/shm/
acda74
acda74
then only the top most (i.e. the last one) is moved. See
acda74
qemuDomainUnshareNamespace() for more info.
acda74
acda74
Now, we could enhance our code to deal with these "doubled" mount
acda74
points. Or, since it is the top most file system that is
acda74
accessible anyways (and this one is preserved), we can
acda74
umount("/dev") in a recursive fashion.
acda74
acda74
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2167302
acda74
Fixes: 379c0ce4bfed8733dfbde557c359eecc5474ce38
acda74
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
acda74
Reviewed-by: Jim Fehlig <jfehlig@suse.com>
acda74
(cherry picked from commit 5155ab4b2a704285505dfea6ffee8b980fdaa29e)
acda74
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
acda74
---
acda74
 src/qemu/qemu_namespace.c | 2 +-
acda74
 1 file changed, 1 insertion(+), 1 deletion(-)
acda74
acda74
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
acda74
index 5769a4dfe0..5fc043bd62 100644
acda74
--- a/src/qemu/qemu_namespace.c
acda74
+++ b/src/qemu/qemu_namespace.c
acda74
@@ -777,7 +777,7 @@ qemuDomainUnshareNamespace(virQEMUDriverConfig *cfg,
acda74
     }
acda74
 
acda74
 #if defined(__linux__)
acda74
-    if (umount("/dev") < 0) {
acda74
+    if (umount2("/dev", MNT_DETACH) < 0) {
acda74
         virReportSystemError(errno, "%s", _("failed to umount devfs on /dev"));
acda74
         return -1;
acda74
     }
acda74
-- 
acda74
2.39.1
acda74