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