[gparted] Don't crash probing libparted unrecognised encrypted file system (#152)



commit 09df074a92eefa4c2f05d6ca8554ee1f75383032
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Thu Apr 8 20:45:19 2021 +0100

    Don't crash probing libparted unrecognised encrypted file system (#152)
    
    Create a LUKS encrypted partition and open it.  Then either leave the
    contents blank or create a file system which libparted doesn't
    recognise, such as: exfat, f2fs, lvm2 pv, minix or reiser4.  When
    GParted probes the disk device it crashes.
    
        # echo -n badpassword | cryptsetup luksFormat /dev/sdb11
        # echo -n badpassword | cryptsetup luksOpen /dev/sdb11 sdb11_crypt
        # ./gpartedbin /dev/sdb
        GParted 1.2.0-git
        configuration (none)
        libparted 3.1
        /dev/mapper/sdb11_crypt: unrecognised disk label
        Segmentation fault (core dumped)
    
    Backtrace:
        #0  0x0000000000460f68 in GParted::GParted_Core::detect_filesystem(_PedDevice*, _PedPartition*, 
std::vector<Glib::ustring, std::allocator<Glib::ustring> >&)
            (lp_device=0x0, lp_partition=0x0, messages=std::vector of length 0, capacity 0)
            at GParted_Core.cc:1235
        #1  0x00000000004615a6 in 
GParted::GParted_Core::detect_filesystem_in_encryption_mapping(Glib::ustring const&, 
std::vector<Glib::ustring, std::allocator<Glib::ustring> >&)
            (path=..., messages=std::vector of length 0, capacity 0)
            at GParted_Core.cc:1096
        #2  0x00000000004647c8 in GParted::GParted_Core::set_luks_partition(GParted::PartitionLUKS&)
            (this=this@entry=0x7fff43f974e0, partition=...)
            at GParted_Core.cc:1011
        #3  0x000000000046511b in GParted::GParted_Core::set_device_partitions(GParted::Device&, _PedDevice*, 
_PedDisk*)
            (this=this@entry=0x7fff43f974e0, device=..., lp_device=0x7efc780008c0, lp_disk=0x7efc78000d10)
            at GParted_Core.cc:883
        #4  0x00000000004658e3 in GParted::GParted_Core::set_device_from_disk(GParted::Device&, Glib::ustring 
const&)
            (this=this@entry=0x7fff43f974e0, device=..., device_path=...)
            at GParted_Core.cc:704
        #5  0x0000000000465fff in GParted::GParted_Core::set_devices_thread(std::vector<GParted::Device, 
std::allocator<GParted::Device> >*)
            (this=0x7fff43f974e0, pdevices=0x7fff43f96bc8)
            at GParted_Core.cc:266
        #6  0x00007efc99ba413d in call_thread_entry_slot ()
            at /lib64/libglibmm-2.4.so.1
        #7  0x00007efc97dc8555 in g_thread_proxy ()
            at /lib64/libglib-2.0.so.0
        #8  0x00007efc96ab4ea5 in start_thread () at /lib64/libpthread.so.0
        #9  0x00007efc967dd9fd in clone () at /lib64/libc.so.6
    
    The relevant sequence of events goes like this:
        detect_filesystem_in_encryption_mapping(path, ...)
          lp_device = NULL
          get_device(path, lp_device)
            lp_device = ped_device_get(path.c_str())
            return true
          lp_disk = NULL
          lp_partition = NULL
          get_disk(lp_device, lp_disk)  // + default parameter strict=true
            lp_disk = ped_disk_new(lp_device)
              // No libparted recognised disk label or file system found, so
              // NULL returned.
            destroy_device_and_disk(lp_device, lp_disk)
              ped_device_destroy(lp_device)
              lp_device = NULL
            return false
          detect_filesystem(lp_device, lp_partition, ...)
            path = lp_device->path
    
    The key points are:
    1. get_device() created a PedDevice object pointed to by lp_device;
    2. get_disk() didn't find a libparted recognised disk label or file
       system but also unexpectedly destroyed the PedDevice object and
       assigned NULL to lp_device;
    3. detect_filesystem() dereferenced lp_device assuming it was still
       valid.
    
    Implement the simplest possible fix by telling get_disk() to not
    destroy the needed PedDevice object when there's no recognised content.
    This is the same as how get_disk() is called in set_device_from_disk().
    
    Closes #152 - GParted crashed when trying to probe an encrypted
                  partition containing content that libparted doesn't
                  recognise

 src/GParted_Core.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
---
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 1a4b2ae6..4fd27743 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -1087,8 +1087,8 @@ FSType GParted_Core::detect_filesystem_in_encryption_mapping(const Glib::ustring
                // supports one block device to one encryption mapping to one file system.
                PedDisk *lp_disk = NULL;
                PedPartition *lp_partition = NULL;
-               if (get_disk(lp_device, lp_disk) && lp_disk->type && lp_disk->type->name &&
-                   strcmp(lp_disk->type->name, "loop") == 0                               )
+               if (get_disk(lp_device, lp_disk, false) && lp_disk && lp_disk->type &&
+                   lp_disk->type->name && strcmp(lp_disk->type->name, "loop") == 0   )
                {
                        lp_partition = ped_disk_next_partition(lp_disk, NULL);
                }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]