verify: also check chunk CryptMode

and in-line verify_stored_chunk to avoid double-loading each chunk.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
Fabian Grünbichler 2020-08-10 13:25:08 +02:00 committed by Dietmar Maurer
parent 14f6c9cb8b
commit 9a38fa29c2
2 changed files with 33 additions and 9 deletions

View File

@ -551,12 +551,6 @@ impl DataStore {
self.chunk_store.insert_chunk(chunk, digest) self.chunk_store.insert_chunk(chunk, digest)
} }
pub fn verify_stored_chunk(&self, digest: &[u8; 32], expected_chunk_size: u64) -> Result<(), Error> {
let blob = self.load_chunk(digest)?;
blob.verify_unencrypted(expected_chunk_size as usize, digest)?;
Ok(())
}
pub fn load_blob(&self, backup_dir: &BackupDir, filename: &str) -> Result<DataBlob, Error> { pub fn load_blob(&self, backup_dir: &BackupDir, filename: &str) -> Result<DataBlob, Error> {
let mut path = self.base_path(); let mut path = self.base_path();
path.push(backup_dir.relative_path()); path.push(backup_dir.relative_path());

View File

@ -40,6 +40,7 @@ fn verify_index_chunks(
index: Box<dyn IndexFile>, index: Box<dyn IndexFile>,
verified_chunks: &mut HashSet<[u8;32]>, verified_chunks: &mut HashSet<[u8;32]>,
corrupt_chunks: &mut HashSet<[u8; 32]>, corrupt_chunks: &mut HashSet<[u8; 32]>,
crypt_mode: CryptMode,
worker: &WorkerTask, worker: &WorkerTask,
) -> Result<(), Error> { ) -> Result<(), Error> {
@ -51,9 +52,38 @@ fn verify_index_chunks(
let info = index.chunk_info(pos).unwrap(); let info = index.chunk_info(pos).unwrap();
let size = info.range.end - info.range.start; let size = info.range.end - info.range.start;
let chunk = match datastore.load_chunk(&info.digest) {
Err(err) => {
corrupt_chunks.insert(info.digest);
worker.log(format!("can't verify chunk, load failed - {}", err));
errors += 1;
continue;
},
Ok(chunk) => chunk,
};
let chunk_crypt_mode = match chunk.crypt_mode() {
Err(err) => {
corrupt_chunks.insert(info.digest);
worker.log(format!("can't verify chunk, unknown CryptMode - {}", err));
errors += 1;
continue;
},
Ok(mode) => mode,
};
if chunk_crypt_mode != crypt_mode {
worker.log(format!(
"chunk CryptMode {:?} does not match index CryptMode {:?}",
chunk_crypt_mode,
crypt_mode
));
errors += 1;
}
if !verified_chunks.contains(&info.digest) { if !verified_chunks.contains(&info.digest) {
if !corrupt_chunks.contains(&info.digest) { if !corrupt_chunks.contains(&info.digest) {
if let Err(err) = datastore.verify_stored_chunk(&info.digest, size) { if let Err(err) = chunk.verify_unencrypted(size as usize, &info.digest) {
corrupt_chunks.insert(info.digest); corrupt_chunks.insert(info.digest);
worker.log(format!("{}", err)); worker.log(format!("{}", err));
errors += 1; errors += 1;
@ -98,7 +128,7 @@ fn verify_fixed_index(
bail!("wrong index checksum"); bail!("wrong index checksum");
} }
verify_index_chunks(datastore, Box::new(index), verified_chunks, corrupt_chunks, worker) verify_index_chunks(datastore, Box::new(index), verified_chunks, corrupt_chunks, info.chunk_crypt_mode(), worker)
} }
fn verify_dynamic_index( fn verify_dynamic_index(
@ -124,7 +154,7 @@ fn verify_dynamic_index(
bail!("wrong index checksum"); bail!("wrong index checksum");
} }
verify_index_chunks(datastore, Box::new(index), verified_chunks, corrupt_chunks, worker) verify_index_chunks(datastore, Box::new(index), verified_chunks, corrupt_chunks, info.chunk_crypt_mode(), worker)
} }
/// Verify a single backup snapshot /// Verify a single backup snapshot