Blob Blame History Raw
From 41d442c08990becc8adac8b6eede016a381d21ec Mon Sep 17 00:00:00 2001
Message-Id: <41d442c08990becc8adac8b6eede016a381d21ec@dist-git>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 11 May 2020 16:40:12 +0200
Subject: [PATCH] virDevMapperGetTargetsImpl: quit early if device is not a
 devmapper target
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

As suggested in the linked bug, libvirt should firstly check
whether the major number of the device is device mapper major.
Because if it isn't subsequent DM_DEVICE_DEPS task may not only
fail, but also yield different results. In the bugzilla this is
demonstrated by creating a devmapper target named 'loop0' and
then creating loop target /dev/loop0. When the latter is then
passed to a domain, our virDevMapperGetTargetsImpl() function
blindly asks devmapper to provide target dependencies for
/dev/loop0 and because of the way devmapper APIs work, it will
'sanitize' the input by using the last component only which is
'loop0' and thus return different results than expected.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1823976

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 01626c668ecfbe465d18799ac4628e6127ea1d47)
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Message-Id: <a3bc79b319dae9f6b4e6813399f2e5dc0ec077df.1589207928.git.mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/util/virdevmapper.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c
index 7da0dba911..a360c3e677 100644
--- a/src/util/virdevmapper.c
+++ b/src/util/virdevmapper.c
@@ -69,6 +69,7 @@ virDevMapperGetTargetsImpl(const char *path,
                            char ***devPaths_ret,
                            unsigned int ttl)
 {
+    struct stat sb;
     struct dm_task *dmt = NULL;
     struct dm_deps *deps;
     struct dm_info info;
@@ -87,6 +88,15 @@ virDevMapperGetTargetsImpl(const char *path,
         return ret;
     }
 
+    if (stat(path, &sb) < 0) {
+        if (errno == ENOENT)
+            return 0;
+        return -1;
+    }
+
+    if (!dm_is_dm_major(major(sb.st_dev)))
+        return 0;
+
     if (!(dmt = dm_task_create(DM_DEVICE_DEPS))) {
         if (errno == ENOENT || errno == ENODEV) {
             /* It's okay. Kernel is probably built without
-- 
2.26.2