Skip to content

Commit

Permalink
Merge pull request #908 from RishabhSaini/pr/cos-1556
Browse files Browse the repository at this point in the history
embed.rs: Added error check when ISO file incomplete
  • Loading branch information
RishabhSaini authored Jul 20, 2022
2 parents 8ff9574 + 4f060f5 commit 54215b6
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Minor changes:
- Detect truncated xz archives
- Fix unlikely decompression error reading initrd
- Add release notes to documentation
- iso: Detect incomplete ISO files

Internal changes:

Expand Down
31 changes: 29 additions & 2 deletions src/iso9660.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,15 @@ pub struct IsoFs {

impl IsoFs {
pub fn from_file(mut file: fs::File) -> Result<Self> {
let length = file.metadata()?.len();
let descriptors = get_volume_descriptors(&mut file)?;
Ok(Self { descriptors, file })
let iso_fs = Self { descriptors, file };
let primary = iso_fs.get_primary_volume_descriptor()?;
if primary.volume_space_size * ISO9660_SECTOR_SIZE as u64 > length {
bail!("ISO image is incomplete");
}

Ok(iso_fs)
}

pub fn as_file(&mut self) -> Result<&mut fs::File> {
Expand Down Expand Up @@ -181,6 +188,7 @@ struct BootVolumeDescriptor {
struct PrimaryVolumeDescriptor {
system_id: String,
volume_id: String,
volume_space_size: u64,
root: Directory,
}

Expand Down Expand Up @@ -298,13 +306,16 @@ 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 = buf.get_u32_le() as u64;
let root = match get_next_directory_record(eat(buf, 156 - 84), 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,
root,
})
}
Expand Down Expand Up @@ -567,13 +578,29 @@ mod tests {
IsoFs::from_file(iso_file).unwrap()
}

#[test]
fn open_truncated_iso() {
let iso_bytes: &[u8] = include_bytes!("../fixtures/iso/synthetic.iso.xz");
let mut decoder = XzDecoder::new(iso_bytes);
let mut iso_file = tempfile().unwrap();
copy(&mut decoder, &mut iso_file).unwrap();
iso_file
.set_len(iso_file.metadata().unwrap().len() / 2)
.unwrap();
assert_eq!(
IsoFs::from_file(iso_file).unwrap_err().to_string(),
"ISO image is incomplete"
);
}

#[test]
fn test_primary_volume_descriptor() {
let iso = open_iso();
let desc = iso.get_primary_volume_descriptor().unwrap();
assert_eq!(desc.system_id, "system-ID-string");
assert_eq!(desc.volume_id, "volume-ID-string");
assert_eq!(desc.root.name, ".");
assert_eq!(desc.volume_space_size, 338);
}

#[test]
Expand Down

0 comments on commit 54215b6

Please sign in to comment.