]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: fix file descriptor leak in blkid_verify()
authorKarel Zak <kzak@redhat.com>
Wed, 31 Jul 2019 14:18:27 +0000 (16:18 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 31 Jul 2019 14:31:10 +0000 (16:31 +0200)
The function blkid_verify() uses private device file descriptor and
uses blkid_probe_set_device() to assign the descriptor to low-level
probing code. Unfortunately, close() in this case is not enough as the
prober can internally open whole-disk device too.

The library API has been extended so blkid_probe_set_device()
deallocates and close previously used prober for whole-disk. This new
functionality is used in blkid_verify() now.

Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1734545
Signed-off-by: Karel Zak <kzak@redhat.com>
libblkid/src/probe.c
libblkid/src/verify.c

index 1ace06a68da1cef9cf2eae35e9193a9e539ecf3d..ae1fc06d6ac8935b690c30eee8c6161a083fdd7c 100644 (file)
@@ -846,10 +846,15 @@ failed:
  * @off: begin of probing area
  * @size: size of probing area (zero means whole device/file)
  *
- * Assigns the device to probe control struct, resets internal buffers and
- * resets the current probing.
+ * Assigns the device to probe control struct, resets internal buffers, resets
+ * the current probing, and close previously associated device (if open by
+ * libblkid).
  *
- * Returns: -1 in case of failure, or 0 on success.
+ * If @fd is < 0 than only resets the prober and returns 1. Note that
+ * blkid_reset_probe() keeps the device associated with the prober, but
+ * blkid_probe_set_device() does complete reset.
+ *
+ * Returns: -1 in case of failure, 0 on success and 1 on reset.
  */
 int blkid_probe_set_device(blkid_probe pr, int fd,
                blkid_loff_t off, blkid_loff_t size)
@@ -864,6 +869,11 @@ int blkid_probe_set_device(blkid_probe pr, int fd,
        if ((pr->flags & BLKID_FL_PRIVATE_FD) && pr->fd >= 0)
                close(pr->fd);
 
+       if (pr->disk_probe) {
+               blkid_free_probe(pr->disk_probe);
+               pr->disk_probe = NULL;
+       }
+
        pr->flags &= ~BLKID_FL_PRIVATE_FD;
        pr->flags &= ~BLKID_FL_TINY_DEV;
        pr->flags &= ~BLKID_FL_CDROM_DEV;
@@ -879,6 +889,9 @@ int blkid_probe_set_device(blkid_probe pr, int fd,
        pr->wipe_size = 0;
        pr->wipe_chain = NULL;
 
+       if (fd < 0)
+               return 1;
+
 #if defined(POSIX_FADV_RANDOM) && defined(HAVE_POSIX_FADVISE)
        /* Disable read-ahead */
        posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
index dbc10f254cf1c7a0537a4aeb06f1d50afa7491be..a78c9f8f2aa4a13ef26f6988797d0206255f5a24 100644 (file)
@@ -184,9 +184,11 @@ blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
                           dev->bid_name, (long long)st.st_rdev, dev->bid_type));
        }
 
-       blkid_reset_probe(cache->probe);
+       /* reset prober */
        blkid_probe_reset_superblocks_filter(cache->probe);
+       blkid_probe_set_device(cache->probe, -1, 0, 0);
        close(fd);
+
        return dev;
 }