From c71892b22930d01ad1ac5fdba0c97ddf2e3067c6 Mon Sep 17 00:00:00 2001 From: RishabhSaini Date: Wed, 6 Jul 2022 18:02:52 -0400 Subject: [PATCH] iso9660.rs: added an error check Added an incomplete file size error check to the ISO9660 parser. --- src/iso9660.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/iso9660.rs b/src/iso9660.rs index 7b82fcf1e..764f49b7c 100644 --- a/src/iso9660.rs +++ b/src/iso9660.rs @@ -49,6 +49,19 @@ pub struct IsoFs { impl IsoFs { pub fn from_file(mut file: fs::File) -> Result { let descriptors = get_volume_descriptors(&mut file)?; + match &descriptors[0] { + VolumeDescriptor::Boot(_boot_volume_descriptor) => {} + VolumeDescriptor::Primary(primary_volume_descriptor) => { + if i64::from(primary_volume_descriptor.volume_space_size) + * i64::from(primary_volume_descriptor.logical_block_size) + >= file.metadata()?.len().try_into().unwrap() + { + bail!("ISO Image is wrong and can't be modified"); + } + } + VolumeDescriptor::Supplementary => {} + VolumeDescriptor::Unknown { type_id: _ } => {} + } Ok(Self { descriptors, file }) } @@ -181,6 +194,8 @@ struct BootVolumeDescriptor { struct PrimaryVolumeDescriptor { system_id: String, volume_id: String, + volume_space_size: i32, + logical_block_size: i16, root: Directory, } @@ -298,13 +313,22 @@ impl PrimaryVolumeDescriptor { parse_iso9660_string(eat(buf, 1), 32, IsoString::StrA).context("parsing system id")?; let volume_id = // technically should be StrD, but non-compliance is common parse_iso9660_string(buf, 32, IsoString::StrA).context("parsing volume id")?; - let root = match get_next_directory_record(eat(buf, 156 - 72), 34, true)? { + eat(buf, 8); // Unused field always 0x00 + let volume_space_size = // Data type: int32_LSB-MSB + buf.get_i32_le(); + assert_eq!(volume_space_size, buf.get_i32()); + eat(buf, 32 + 4 + 4); // Ignoring the following fields (Unused, Volume Set Size, Volume Sequence Number) + let logical_block_size = buf.get_i16_le(); + assert_eq!(logical_block_size, buf.get_i16()); + let root = match get_next_directory_record(eat(buf, 156 - 132), 34, true)? { Some(DirectoryRecord::Directory(d)) => d, _ => bail!("failed to parse root directory record from primary descriptor"), }; Ok(Self { system_id, volume_id, + volume_space_size, + logical_block_size, root, }) }