From 26080f264ad2d0c57d4241750f6cade7bb040f23 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 4 Jul 2026 09:02:48 +0200 Subject: [PATCH] block: vhd: Read the VHD footer positionally Read the trailing footer sector with query_device_size and read_exact_at instead of seeking to the end of the AlignedFile and reading through its cursor. Signed-off-by: Anatol Belski --- block/src/formats/vhd/internal/footer.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/block/src/formats/vhd/internal/footer.rs b/block/src/formats/vhd/internal/footer.rs index 72bc9d9e5..0bb07952e 100644 --- a/block/src/formats/vhd/internal/footer.rs +++ b/block/src/formats/vhd/internal/footer.rs @@ -3,9 +3,10 @@ // SPDX-License-Identifier: Apache-2.0 use std::fs::File; -use std::io::{self, Read, Seek, SeekFrom}; +use std::io; +use std::os::unix::fs::FileExt; -use crate::AlignedFile; +use crate::{AlignedFile, query_device_size}; // Production code uses: cookie, file_format_version, data_offset, // current_size, disk_type. The remaining fields are parsed for VHD @@ -32,10 +33,13 @@ pub struct VhdFooter { impl VhdFooter { pub fn new(file: &mut File) -> io::Result { - let mut aligned = AlignedFile::new(file.try_clone()?, true); - aligned.seek(SeekFrom::End(-512))?; + let aligned = AlignedFile::new(file.try_clone()?, true); + let size = query_device_size(file)?.0; + let footer_offset = size.checked_sub(512).ok_or_else(|| { + io::Error::new(io::ErrorKind::InvalidInput, "file too small for VHD footer") + })?; let mut sector = [0u8; 512]; - aligned.read_exact(&mut sector)?; + aligned.read_exact_at(&mut sector, footer_offset)?; Ok(VhdFooter { cookie: u64::from_be_bytes(sector[0..8].try_into().unwrap()),