mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Keep generation ambiguous for legacy hashes in check repair to prevent false CURRENT certification on size changes
Some checks are pending
Build / build-mac (push) Waiting to run
Build / build-linux (push) Waiting to run
Build / build-arm32 (push) Waiting to run
Build / build-win (push) Waiting to run
Build / build-freebsd (push) Waiting to run
Build / build-musl (push) Waiting to run
CodeQL Advanced / Analyze (c-cpp) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
Some checks are pending
Build / build-mac (push) Waiting to run
Build / build-linux (push) Waiting to run
Build / build-arm32 (push) Waiting to run
Build / build-win (push) Waiting to run
Build / build-freebsd (push) Waiting to run
Build / build-musl (push) Waiting to run
CodeQL Advanced / Analyze (c-cpp) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
This commit is contained in:
parent
b82ee5ff56
commit
c09b850047
3 changed files with 38 additions and 25 deletions
|
|
@ -988,23 +988,33 @@ static int repair(struct snapraid_state* state, int rehash, block_off_t pos, uns
|
|||
if (!mem_is_zero(buffer[failed[j].index], state->block_size))
|
||||
current_generation_proven = 1;
|
||||
} else {
|
||||
size_t pos_size;
|
||||
unsigned hash_kind;
|
||||
|
||||
pos_size = file_block_size(failed[j].file, failed[j].file_pos, state->block_size);
|
||||
hash_kind = rehash ? state->prevhash : state->hash;
|
||||
|
||||
/*
|
||||
* The stored CHG hash identifies OLD contents under the recovery invariant.
|
||||
* Generation detection must compare hash identity only and must not apply the
|
||||
* CURRENT logical-size padding requirement. With MuseAir the hash covers the
|
||||
* complete canonical RAID block, so a mismatch proves candidate != OLD and
|
||||
* therefore identifies this validated RAID solution as CURRENT.
|
||||
* CURRENT logical-size padding requirement.
|
||||
*
|
||||
* Legacy hashes still depend on the logical size used to compute the hash.
|
||||
* The OLD logical size is not available here, so size-changing CHG blocks may
|
||||
* remain subject to the historical ambiguity with Murmur3/Spooky2.
|
||||
* When the hash covers the complete canonical RAID block (memhash_is_block()),
|
||||
* candidate identity is independent of logical size: a mismatch proves
|
||||
* candidate != OLD and therefore identifies this validated RAID solution as CURRENT.
|
||||
*
|
||||
* For hashes that depend on the logical size (Murmur3/Spooky2), the OLD
|
||||
* logical size is not available. Because a mismatch against CURRENT pos_size
|
||||
* cannot distinguish candidate != OLD from a change in file size, the
|
||||
* conservative approach keeps the generation ambiguous and does not treat
|
||||
* the mismatch as proof of CURRENT.
|
||||
*/
|
||||
if (block_hash_cmp(state, rehash, failed[j].block, pos_size, buffer[failed[j].index]) != 0)
|
||||
current_generation_proven = 1;
|
||||
if (memhash_is_block(hash_kind)) {
|
||||
size_t pos_size;
|
||||
|
||||
pos_size = file_block_size(failed[j].file, failed[j].file_pos, state->block_size);
|
||||
|
||||
if (block_hash_cmp(state, rehash, failed[j].block, pos_size, buffer[failed[j].index]) != 0)
|
||||
current_generation_proven = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -779,29 +779,19 @@ void memhash_block(unsigned kind, const unsigned char* seed, void* digest, const
|
|||
{
|
||||
assert(logical_size <= block_size);
|
||||
|
||||
switch (kind) {
|
||||
case HASH_MUSEAIR :
|
||||
if (memhash_is_block(kind)) {
|
||||
/*
|
||||
* MuseAir defines the identity of the complete canonical RAID
|
||||
* block. The caller must have zero-padded the buffer after the
|
||||
* logical end of the file block.
|
||||
* Canonical block hashes define the identity of the complete
|
||||
* canonical RAID block. The caller must have zero-padded the
|
||||
* buffer after the logical end of the file block.
|
||||
*/
|
||||
memhash(kind, seed, digest, src, block_size);
|
||||
break;
|
||||
case HASH_MURMUR3 :
|
||||
case HASH_SPOOKY2 :
|
||||
} else {
|
||||
/*
|
||||
* Preserve the historical SnapRAID hash semantics for content
|
||||
* files using legacy hashes.
|
||||
*/
|
||||
memhash(kind, seed, digest, src, logical_size);
|
||||
break;
|
||||
default :
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EINTERNAL, "Internal inconsistency in hash function %u\n", kind);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -282,6 +282,19 @@ void memhash(unsigned kind, const unsigned char* seed, void* digest, const void*
|
|||
*/
|
||||
void memhash_block(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t logical_size, size_t block_size);
|
||||
|
||||
/**
|
||||
* Return !=0 if the hash kind operates on the complete canonical RAID block.
|
||||
*
|
||||
* Legacy hashes (Murmur3, Spooky2) preserve historical semantics and hash
|
||||
* only the logical file bytes.
|
||||
* Modern hashes (MuseAir) hash the complete zero-padded RAID block up to
|
||||
* block_size.
|
||||
*/
|
||||
static inline int memhash_is_block(unsigned kind)
|
||||
{
|
||||
return kind == HASH_MUSEAIR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hash name.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue