From 16ff6b7cd8d2ab73cf6b431d0b1e2fbf8772c477 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Fri, 14 Jun 2019 08:57:52 +0200 Subject: [PATCH] src/backup/dynamic_index.rs: compute checksum over the index --- src/backup/dynamic_index.rs | 38 +++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/backup/dynamic_index.rs b/src/backup/dynamic_index.rs index 9af4e0e5..d2ac9064 100644 --- a/src/backup/dynamic_index.rs +++ b/src/backup/dynamic_index.rs @@ -28,7 +28,9 @@ pub struct DynamicIndexHeader { pub version: u32, pub uuid: [u8; 16], pub ctime: u64, - reserved: [u8; 4056], // overall size is one page (4096 bytes) + /// Sha256 over the index ``SHA256(offset1||digest1||offset2||digest2||...)`` + pub index_csum: [u8; 32], + reserved: [u8; 4024], // overall size is one page (4096 bytes) } @@ -41,6 +43,7 @@ pub struct DynamicIndexReader { index_entries: usize, pub uuid: [u8; 16], pub ctime: u64, + pub index_csum: [u8; 32], } // `index` is mmap()ed which cannot be thread-local so should be sendable @@ -119,6 +122,7 @@ impl DynamicIndexReader { index_entries: index_size/40, ctime, uuid: header.uuid, + index_csum: header.index_csum, }) } @@ -382,6 +386,7 @@ pub struct DynamicIndexWriter { closed: bool, filename: PathBuf, tmp_filename: PathBuf, + csum: Option, pub uuid: [u8; 16], pub ctime: u64, } @@ -429,8 +434,12 @@ impl DynamicIndexWriter { header.ctime = u64::to_le(ctime); header.uuid = *uuid.as_bytes(); + header.index_csum = [0u8; 32]; + writer.write_all(&buffer)?; + let csum = Some(openssl::sha::Sha256::new()); + Ok(Self { store, _lock: shared_lock, @@ -440,6 +449,7 @@ impl DynamicIndexWriter { tmp_filename: tmp_path, ctime, uuid: *uuid.as_bytes(), + csum, }) } @@ -448,7 +458,7 @@ impl DynamicIndexWriter { self.store.insert_chunk(chunk) } - pub fn close(&mut self) -> Result<(), Error> { + pub fn close(&mut self) -> Result<[u8; 32], Error> { if self.closed { bail!("cannot close already closed archive index file {:?}", self.filename); @@ -458,11 +468,23 @@ impl DynamicIndexWriter { self.writer.flush()?; + use std::io::Seek; + + let csum_offset = proxmox::tools::offsetof!(DynamicIndexHeader, index_csum); + self.writer.seek(std::io::SeekFrom::Start(csum_offset as u64))?; + + let csum = self.csum.take().unwrap(); + let index_csum = csum.finish(); + + self.writer.write_all(&index_csum)?; + self.writer.flush()?; + + if let Err(err) = std::fs::rename(&self.tmp_filename, &self.filename) { bail!("Atomic rename file {:?} failed - {}", self.filename, err); } - Ok(()) + Ok(index_csum) } // fixme: rename to add_digest @@ -470,7 +492,15 @@ impl DynamicIndexWriter { if self.closed { bail!("cannot write to closed dynamic index file {:?}", self.filename); } - self.writer.write(unsafe { &std::mem::transmute::(offset.to_le()) })?; + + let offset_le: &[u8; 8] = unsafe { &std::mem::transmute::(offset.to_le()) }; + + if let Some(ref mut csum) = self.csum { + csum.update(offset_le); + csum.update(digest); + } + + self.writer.write(offset_le)?; self.writer.write(digest)?; Ok(()) }