03cc27
From 41d442c08990becc8adac8b6eede016a381d21ec Mon Sep 17 00:00:00 2001
03cc27
Message-Id: <41d442c08990becc8adac8b6eede016a381d21ec@dist-git>
03cc27
From: Michal Privoznik <mprivozn@redhat.com>
03cc27
Date: Mon, 11 May 2020 16:40:12 +0200
03cc27
Subject: [PATCH] virDevMapperGetTargetsImpl: quit early if device is not a
03cc27
 devmapper target
03cc27
MIME-Version: 1.0
03cc27
Content-Type: text/plain; charset=UTF-8
03cc27
Content-Transfer-Encoding: 8bit
03cc27
03cc27
As suggested in the linked bug, libvirt should firstly check
03cc27
whether the major number of the device is device mapper major.
03cc27
Because if it isn't subsequent DM_DEVICE_DEPS task may not only
03cc27
fail, but also yield different results. In the bugzilla this is
03cc27
demonstrated by creating a devmapper target named 'loop0' and
03cc27
then creating loop target /dev/loop0. When the latter is then
03cc27
passed to a domain, our virDevMapperGetTargetsImpl() function
03cc27
blindly asks devmapper to provide target dependencies for
03cc27
/dev/loop0 and because of the way devmapper APIs work, it will
03cc27
'sanitize' the input by using the last component only which is
03cc27
'loop0' and thus return different results than expected.
03cc27
03cc27
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1823976
03cc27
03cc27
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
03cc27
Reviewed-by: Ján Tomko <jtomko@redhat.com>
03cc27
(cherry picked from commit 01626c668ecfbe465d18799ac4628e6127ea1d47)
03cc27
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
03cc27
Message-Id: <a3bc79b319dae9f6b4e6813399f2e5dc0ec077df.1589207928.git.mprivozn@redhat.com>
03cc27
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
03cc27
---
03cc27
 src/util/virdevmapper.c | 10 ++++++++++
03cc27
 1 file changed, 10 insertions(+)
03cc27
03cc27
diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c
03cc27
index 7da0dba911..a360c3e677 100644
03cc27
--- a/src/util/virdevmapper.c
03cc27
+++ b/src/util/virdevmapper.c
03cc27
@@ -69,6 +69,7 @@ virDevMapperGetTargetsImpl(const char *path,
03cc27
                            char ***devPaths_ret,
03cc27
                            unsigned int ttl)
03cc27
 {
03cc27
+    struct stat sb;
03cc27
     struct dm_task *dmt = NULL;
03cc27
     struct dm_deps *deps;
03cc27
     struct dm_info info;
03cc27
@@ -87,6 +88,15 @@ virDevMapperGetTargetsImpl(const char *path,
03cc27
         return ret;
03cc27
     }
03cc27
 
03cc27
+    if (stat(path, &sb) < 0) {
03cc27
+        if (errno == ENOENT)
03cc27
+            return 0;
03cc27
+        return -1;
03cc27
+    }
03cc27
+
03cc27
+    if (!dm_is_dm_major(major(sb.st_dev)))
03cc27
+        return 0;
03cc27
+
03cc27
     if (!(dmt = dm_task_create(DM_DEVICE_DEPS))) {
03cc27
         if (errno == ENOENT || errno == ENODEV) {
03cc27
             /* It's okay. Kernel is probably built without
03cc27
-- 
03cc27
2.26.2
03cc27