Mykola Ivanets
2018-Jun-01 04:59 UTC
[Libguestfs] [PATCH v2] daemon: inspect: better handling windows drive mapping.
I saw several Windows disk images which contains strange registry entry for mapped drives: "\\DosDevices\\Y:"=hex(3):00,00,00,00,00,00,00,00,00,00,00,00 Which is decoded something like diskID = 0x0, partition starts at 0 bytes offset from the start of the disk. In addition to a Windows disk image, I have attached dummy disk and made xfs file system on a whole device without partitioning it. I mount xfs file system to a "/" and then mkdir and mount other found file systems inside (/fs1, /fs2 etc.). When we decode drive mappings we are looking for a disk with ID 0x0 (it is 4 bytes somewhere LBA0). It is appeared that dummy non-partitioned disk with xfs file system has zeros by offset where diskID is expected to be). So the disk is considered as a candidate to search for partition at offset 0. part-list command (and "parted" which is used under the hood) reports there is 1 partition on "dummy" disk which starts exactly at offset 0. And thus dummy device name and partition number are simply concatenated together and corresponding drive mapping is returned: Y => /dev/sdX1. But /dev/sdX1 is not existing block device. No matter either it is a bug in "parted" (or it works this way by-design), let's protect ourself from this situation: in addition we look for msdos partition table on a disk before making any further assumptions. --- daemon/inspect_fs_windows.ml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/daemon/inspect_fs_windows.ml b/daemon/inspect_fs_windows.ml index 8b2aad8d3..af52dee2d 100644 --- a/daemon/inspect_fs_windows.ml +++ b/daemon/inspect_fs_windows.ml @@ -329,7 +329,7 @@ and get_drive_mappings h root data String.is_prefix blob "DMIO:ID:" (* GPT *) then map_registry_disk_blob_gpt (Lazy.force partitions) blob else if String.length blob = 12 then - map_registry_disk_blob (Lazy.force devices) blob + map_registry_disk_blob_mbr (Lazy.force devices) blob else None ) @@ -356,13 +356,18 @@ and get_drive_mappings h root data * The following function maps this blob to a libguestfs partition * name, if possible. *) -and map_registry_disk_blob devices blob +and map_registry_disk_blob_mbr devices blob try (* First 4 bytes are the disk ID. Search all devices to find the * disk with this disk ID. *) let diskid = String.sub blob 0 4 in - let device = List.find (fun dev -> pread dev 4 0x01b8 = diskid) devices in + let device + List.find ( + fun dev -> + Parted.part_get_parttype dev = "msdos" && + pread dev 4 0x01b8 = diskid + ) devices in (* Next 8 bytes are the offset of the partition in bytes(!) given as * a 64 bit little endian number. Luckily it's easy to get the -- 2.17.0
Richard W.M. Jones
2018-Jun-01 12:49 UTC
[Libguestfs] [PATCH v2] daemon: inspect: better handling windows drive mapping.
On Fri, Jun 01, 2018 at 07:59:51AM +0300, Mykola Ivanets wrote:> I saw several Windows disk images which contains strange registry entry > for mapped drives: > > "\\DosDevices\\Y:"=hex(3):00,00,00,00,00,00,00,00,00,00,00,00 > > Which is decoded something like diskID = 0x0, partition starts at 0 > bytes offset from the start of the disk. In addition to a Windows disk > image, I have attached dummy disk and made xfs file system on a whole > device without partitioning it. I mount xfs file system to a "/" and > then mkdir and mount other found file systems inside (/fs1, /fs2 etc.). > > When we decode drive mappings we are looking for a disk with ID 0x0 (it > is 4 bytes somewhere LBA0). It is appeared that dummy non-partitioned > disk with xfs file system has zeros by offset where diskID is expected > to be). So the disk is considered as a candidate to search for > partition at offset 0. part-list command (and "parted" which is used > under the hood) reports there is 1 partition on "dummy" disk which > starts exactly at offset 0. And thus dummy device name and partition > number are simply concatenated together and corresponding drive mapping > is returned: Y => /dev/sdX1. But /dev/sdX1 is not existing block > device. > > No matter either it is a bug in "parted" (or it works this way > by-design), let's protect ourself from this situation: in addition we > look for msdos partition table on a disk before making any further > assumptions. > --- > daemon/inspect_fs_windows.ml | 11 ++++++++--- > 1 file changed, 8 insertions(+), 3 deletions(-) > > diff --git a/daemon/inspect_fs_windows.ml b/daemon/inspect_fs_windows.ml > index 8b2aad8d3..af52dee2d 100644 > --- a/daemon/inspect_fs_windows.ml > +++ b/daemon/inspect_fs_windows.ml > @@ -329,7 +329,7 @@ and get_drive_mappings h root data > String.is_prefix blob "DMIO:ID:" (* GPT *) then > map_registry_disk_blob_gpt (Lazy.force partitions) blob > else if String.length blob = 12 then > - map_registry_disk_blob (Lazy.force devices) blob > + map_registry_disk_blob_mbr (Lazy.force devices) blob > else > None > ) > @@ -356,13 +356,18 @@ and get_drive_mappings h root data > * The following function maps this blob to a libguestfs partition > * name, if possible. > *) > -and map_registry_disk_blob devices blob > +and map_registry_disk_blob_mbr devices blob > try > (* First 4 bytes are the disk ID. Search all devices to find the > * disk with this disk ID. > *) > let diskid = String.sub blob 0 4 in > - let device = List.find (fun dev -> pread dev 4 0x01b8 = diskid) devices in > + let device > + List.find ( > + fun dev -> > + Parted.part_get_parttype dev = "msdos" && > + pread dev 4 0x01b8 = diskid > + ) devices inLooks sensible, ACK. Will push it in a bit, thanks. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-builder quickly builds VMs from scratch http://libguestfs.org/virt-builder.1.html
Reasonably Related Threads
- [PATCH] daemon: inspect: better handling windows drive mapping.
- [PATCH] daemon: inspect_fs_windows: Handle parted errors
- Re: [PATCH] daemon: inspect_fs_windows: Handle parted errors
- Re: [PATCH] daemon: inspect_fs_windows: Handle parted errors
- [PATCH v11 09/10] daemon: Implement inspection of Windows.