]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: check for private DM device before open
authorZdenek Kabelac <zkabelac@redhat.com>
Sat, 14 Mar 2026 13:39:41 +0000 (14:39 +0100)
committerZdenek Kabelac <zkabelac@redhat.com>
Sat, 14 Mar 2026 13:39:41 +0000 (14:39 +0100)
blkid_new_probe_from_filename() opens the device before calling
blkid_probe_set_device(), which checks sysfs_devno_is_dm_private()
and sets BLKID_FL_NOSCAN_DEV.  But the open() itself bumps the
kernel open count, so a concurrent DM_DEVICE_REMOVE ioctl sees
EBUSY even though blkid never actually probes the device.

Move the private-device check before open() in
blkid_new_probe_from_filename().  The sysfs UUID is readable
without opening the block device, so this closes the race window
between udev-worker's blkid builtin and device-mapper remove.

Note: blkid_verify() in verify.c already does the check before
open() -- this patch makes the probe path consistent.

Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
libblkid/src/probe.c

index 60af2915c0d76e2d5911b8b5ca730f27d2e0d909..d47c22c720433d0826835f11b6260f30833147b8 100644 (file)
@@ -216,8 +216,18 @@ blkid_probe blkid_new_probe_from_filename(const char *filename)
 {
        int fd;
        blkid_probe pr = NULL;
+       struct stat sb;
+
+       /*
+        * Check for private device-mapper devices (LVM internals, etc.)
+        * before open() to avoid bumping the kernel open count.  A racing
+        * DM_DEVICE_REMOVE would otherwise see EBUSY.
+        */
+       if (stat(filename, &sb) == 0 && S_ISBLK(sb.st_mode) &&
+           sysfs_devno_is_dm_private(sb.st_rdev, NULL))
+               return NULL;
 
-       fd = open(filename, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
+       fd = open(filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
        if (fd < 0)
                return NULL;