@@ -488,6 +488,7 @@ class VHDXInspector(FileInspector):
488
488
"""
489
489
METAREGION = '8B7CA206-4790-4B9A-B8FE-575F050F886E'
490
490
VIRTUAL_DISK_SIZE = '2FA54224-CD1B-4876-B211-5DBED83BF4B8'
491
+ VHDX_METADATA_TABLE_MAX_SIZE = 32 * 2048 # From qemu
491
492
492
493
def __init__ (self , * a , ** k ):
493
494
super (VHDXInspector , self ).__init__ (* a , ** k )
@@ -602,6 +603,8 @@ def _find_meta_entry(self, desired_guid):
602
603
item_offset , item_length , _reserved = struct .unpack (
603
604
'<III' ,
604
605
meta_buffer [entry_offset + 16 :entry_offset + 28 ])
606
+ item_length = min (item_length ,
607
+ self .VHDX_METADATA_TABLE_MAX_SIZE )
605
608
self .region ('metadata' ).length = len (meta_buffer )
606
609
self ._log .debug ('Found entry at offset %x' , item_offset )
607
610
# Metadata item offset is from the beginning of the metadata
@@ -652,7 +655,7 @@ def __str__(self):
652
655
#
653
656
# https://www.vmware.com/app/vmdk/?src=vmdk
654
657
class VMDKInspector (FileInspector ):
655
- """vmware VMDK format (monolithicSparse variant only)
658
+ """vmware VMDK format (monolithicSparse and streamOptimized variants only)
656
659
657
660
This needs to store the 512 byte header and the descriptor region
658
661
which should be just after that. The descriptor region is some
@@ -683,7 +686,6 @@ def post_process(self):
683
686
684
687
if sig != b'KDMV' :
685
688
raise ImageFormatError ('Signature KDMV not found: %r' % sig )
686
- return
687
689
688
690
if ver not in (1 , 2 , 3 ):
689
691
raise ImageFormatError ('Unsupported format version %i' % ver )
@@ -693,9 +695,18 @@ def post_process(self):
693
695
# header, which we cannot support since we stream.
694
696
raise ImageFormatError ('Unsupported VMDK footer' )
695
697
698
+ # Since we parse both desc_sec and desc_num (the location of the
699
+ # VMDK's descriptor, expressed in 512 bytes sectors) we enforce a
700
+ # check on the bounds to create a reasonable CaptureRegion. This
701
+ # is similar to how it's done in qemu.
702
+ desc_offset = desc_sec * 512
703
+ desc_size = min (desc_num * 512 , self .DESC_MAX_SIZE )
704
+ if desc_offset != self .DESC_OFFSET :
705
+ raise ImageFormatError ("Wrong descriptor location" )
706
+
696
707
if not self .has_region ('descriptor' ):
697
708
self .new_region ('descriptor' , CaptureRegion (
698
- desc_sec * 512 , desc_num * 512 ))
709
+ desc_offset , desc_size ))
699
710
700
711
@property
701
712
def format_match (self ):
@@ -721,7 +732,7 @@ def virtual_size(self):
721
732
vmdktype = descriptor [type_idx :type_end ]
722
733
else :
723
734
vmdktype = b'formatnotfound'
724
- if vmdktype != b'monolithicSparse' :
735
+ if vmdktype not in ( b'monolithicSparse' , b'streamOptimized' ) :
725
736
LOG .warning ('Unsupported VMDK format %s' , vmdktype )
726
737
return 0
727
738
0 commit comments