[gparted] Add loading of LUKS mapping offset and length (#760080)



commit 317e44405689270efb806e5bfdab5fec8e923055
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Sun Apr 19 14:08:20 2015 +0100

    Add loading of LUKS mapping offset and length (#760080)
    
    Also load the starting offset and length of the active dm-crypt mapping
    into the LUKS_Info module from the dmsetup output.  This provides the
    location and size of the encrypted data within the underlying block
    device.
    
    Note that dmsetup reports in units of 512 bytes sectors [1], the GParted
    LUKS_Info module uses bytes and GParted Partition objects work in device
    sector size units.  However the actual sector size of a dm-crypt mapping
    [2] is the same as that of the underlying block device [3].
    
        # modprobe scsi_debug dev_size_mb=128 sector_size=4096
        # fgrep scsi_debug /sys/block/*/device/model
        /sys/block/sdd/device/model:scsi_debug
        # parted /dev/sde print
        Error: /dev/sde: unrecognised disk label
        Model: Linux scsi_debug (scsi)
        Disk /dev/sde: 134MB
    [3] Sector size (logical/physical): 4096B/4096B
        Partition Table: unknown
    
        # cryptsetup luksFormat /dev/sde
        # cryptsetup luksOpen /dev/sde sde_crypt
        # parted /dev/mapper/sde_crypt print
        Error: /dev/mapper/sde_crypt: unrecognised disk label
        Model: Linux device-mapper (crypt) (dm)
        Disk /dev/mapper/sde_crypt: 132MB
    [2] Sector size (logical/physical): 4096B/4096B
        Partition Table: unknown
    
        # cryptsetup status sde_crypt
        /dev/mapper/sde_crypt is active.
          type:  LUKS1
          cipher:  aes-cbc-essiv:sha256
          keysize: 256 bits
          device:  /dev/sde
          offset:  4096 sectors
          size:    258048 sectors
          mode:    read/write
        # dmsetup table --target crypt
        ...
        sde_crypt: 0 258048 crypt aes-cbc-essiv:sha256 
0000000000000000000000000000000000000000000000000000000000000000 0 8:64 4096
    
    [1] Both cryptsetup and dmsetup report the offset as 4096 and the size/
    length as 258048.  128 MiB / (4096+258048) = 512 byte units, even on a
    4096 byte sector size device.
    
    Update debugging of LUKS to this:
    
        # ./gpartedbin
        ======================
        libparted : 2.4
        ======================
        DEBUG: /dev/sdb5: LUKS closed
        DEBUG: /dev/sdb6: LUKS open mapping /dev/mapper/sdb6_crypt, offset=2097152, length=534773760
        /dev/sde: unrecognised disk label
        DEBUG: /dev/sde: LUKS open mapping /dev/mapper/sde_crypt, offset=2097152, length=132120576
    
    Bug 760080 - Implement read-only LUKS support

 include/LUKS_Info.h |   18 +++++++++++++++++-
 src/GParted_Core.cc |    7 ++++---
 src/LUKS_Info.cc    |   48 +++++++++++++++++++++++++++++-------------------
 src/luks.cc         |    4 ++--
 4 files changed, 52 insertions(+), 25 deletions(-)
---
diff --git a/include/LUKS_Info.h b/include/LUKS_Info.h
index 2ddff33..b7e287f 100644
--- a/include/LUKS_Info.h
+++ b/include/LUKS_Info.h
@@ -25,16 +25,32 @@
 #ifndef GPARTED_LUKS_INFO_H
 #define GPARTED_LUKS_INFO_H
 
+#include "../include/Utils.h"
+
 #include <glibmm/ustring.h>
+#include <vector>
 
 namespace GParted
 {
 
+struct LUKS_Mapping
+{
+       Glib::ustring name;    // Name of the dm-crypt mapping
+       unsigned long major;   // Major device number of the underlying block device
+       unsigned long minor;   // Minor device number of the underlying block device
+       Glib::ustring path;    // Path of the underlying block device
+       Byte_Value    offset;  // Offset to the start of the mapping in the underlying block device
+       Byte_Value    length;  // Length of the mapping in the underlying block device
+};
+
 class LUKS_Info
 {
 public:
        static void load_cache();
-       static Glib::ustring get_mapping_name( const Glib::ustring & path );
+       static const LUKS_Mapping & get_cache_entry( const Glib::ustring & path );
+
+private:
+       static std::vector<LUKS_Mapping> luks_mapping_cache;
 };
 
 }//GParted
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 52be0e5..96f7513 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -1425,12 +1425,13 @@ void GParted_Core::set_device_one_partition( Device & device, PedDevice * lp_dev
 void GParted_Core::debug_luks_partition( Partition & partition )
 {
        // FIXME: Temporary debugging of LUKS mapping.
-       Glib::ustring name = LUKS_Info::get_mapping_name( partition.get_path() );
-       if ( name.empty() )
+       LUKS_Mapping mapping = LUKS_Info::get_cache_entry( partition.get_path() );
+       if ( mapping.name.empty() )
                std::cout << "DEBUG: " << partition.get_path() << ": LUKS closed" << std::endl;
        else
                std::cout << "DEBUG: " << partition.get_path()
-                         << ": LUKS open mapping " << DEV_MAPPER_PATH << name << std::endl;
+                         << ": LUKS open mapping " << DEV_MAPPER_PATH << mapping.name << ", offset=" << 
mapping.offset
+                         << ", length=" << mapping.length << std::endl;
 }
 
 void GParted_Core::set_partition_label_and_uuid( Partition & partition )
diff --git a/src/LUKS_Info.cc b/src/LUKS_Info.cc
index 535e795..c3b6f11 100644
--- a/src/LUKS_Info.cc
+++ b/src/LUKS_Info.cc
@@ -18,6 +18,7 @@
 #include "../include/Utils.h"
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -25,18 +26,10 @@
 namespace GParted
 {
 
-struct LUKS_Mapping
-{
-       Glib::ustring name;   // Name of the dm-crypt mapping
-       unsigned long major;  // Major device number of the underlying block device
-       unsigned long minor;  // Minor device number of the underlying block device
-       Glib::ustring path;   // Path of the underlying block device
-};
-
 // Cache of active dm-crypt mappings.
 // Example entry:
-//     {name="sdb6_crypt", major=8, minor=22, path="/dev/sdb6"}
-static std::vector<LUKS_Mapping> luks_mapping_cache;
+//     {name="sdb6_crypt", major=8, minor=22, path="/dev/sdb6", offset=2097152, length=534773760}
+std::vector<LUKS_Mapping> LUKS_Info::luks_mapping_cache;
 
 void LUKS_Info::load_cache()
 {
@@ -63,9 +56,11 @@ void LUKS_Info::load_cache()
                std::vector<Glib::ustring> fields;
                Utils::tokenize( lines[i], fields, " " );
                const unsigned DMCRYPT_FIELD_Name    = 0;
+               const unsigned DMCRYPT_FIELD_length  = 2;
                const unsigned DMCRYPT_FIELD_devpath = 7;
+               const unsigned DMCRYPT_FIELD_offset  = 8;
 
-               if ( fields.size() <= DMCRYPT_FIELD_devpath )
+               if ( fields.size() <= DMCRYPT_FIELD_offset )
                        continue;
 
                // Extract LUKS mapping name
@@ -81,8 +76,8 @@ void LUKS_Info::load_cache()
                luks_map.minor = 0UL;
                luks_map.path.clear();
                Glib::ustring devpath = fields[DMCRYPT_FIELD_devpath];
-               unsigned long maj = 0;
-               unsigned long min = 0;
+               unsigned long maj = 0UL;
+               unsigned long min = 0UL;
                if ( devpath.length() > 0 && devpath[0] == '/' )
                        luks_map.path = devpath;
                else if ( sscanf( devpath.c_str(), "%lu:%lu", &maj, &min ) == 2 )
@@ -93,20 +88,34 @@ void LUKS_Info::load_cache()
                else
                        continue;
 
+               // Extract LUKS offset and length.  Dm-crypt reports all sizes in units of
+               // 512 byte sectors.
+               luks_map.offset = -1LL;
+               luks_map.length = -1LL;
+               Byte_Value offset = atoll( fields[DMCRYPT_FIELD_offset].c_str() );
+               Byte_Value length = atoll( fields[DMCRYPT_FIELD_length].c_str() );
+               if ( offset > 0LL && length > 0LL )
+               {
+                       luks_map.offset = offset * 512LL;
+                       luks_map.length = length * 512LL;
+               }
+               else
+                       continue;
+
                luks_mapping_cache.push_back( luks_map );
        }
 }
 
-// Return name of the active LUKS mapping for the underlying block device path,
-// or "" when no such mapping exists.
-Glib::ustring LUKS_Info::get_mapping_name( const Glib::ustring & path )
+// Return LUKS cache entry for the named underlying block device path,
+// or not found substitute when no entry exists.
+const LUKS_Mapping & LUKS_Info::get_cache_entry( const Glib::ustring & path )
 {
        // First scan the cache looking for an underlying block device path match.
        // (Totally in memory)
        for ( unsigned int i = 0 ; i < luks_mapping_cache.size() ; i ++ )
        {
                if ( path == luks_mapping_cache[i].path )
-                       return luks_mapping_cache[i].name;
+                       return luks_mapping_cache[i];
        }
 
        // Second scan the cache looking for an underlying block device major, minor
@@ -124,12 +133,13 @@ Glib::ustring LUKS_Info::get_mapping_name( const Glib::ustring & path )
                                // query for the same path.
                                luks_mapping_cache[i].path = path;
 
-                               return luks_mapping_cache[i].name;
+                               return luks_mapping_cache[i];
                        }
                }
        }
 
-       return "";
+       static LUKS_Mapping not_found = {"", 0UL, 0UL, "", -1LL, -1LL};
+       return not_found;
 }
 
 //Private methods
diff --git a/src/luks.cc b/src/luks.cc
index 608e263..396c373 100644
--- a/src/luks.cc
+++ b/src/luks.cc
@@ -33,8 +33,8 @@ FS luks::get_filesystem_support()
 
 bool luks::is_busy( const Glib::ustring & path )
 {
-       Glib::ustring name = LUKS_Info::get_mapping_name( path );
-       return ! name.empty();
+       LUKS_Mapping mapping = LUKS_Info::get_cache_entry( path );
+       return ! mapping.name.empty();
 }
 
 } //GParted


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