Reject duplicate or misplaced blockmax records in content decoding

This commit is contained in:
Andrea Mazzoleni 2026-08-27 22:27:52 +02:00
parent 7767f45984
commit 4833fdf21b

View file

@ -2220,6 +2220,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
uint64_t count_unscrubbed;
int crc_checked;
int has_block_size;
int has_blockmax;
int has_hash_size;
int has_hash;
int has_prevhash;
@ -2241,6 +2242,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
count_unscrubbed = 0;
crc_checked = 0;
has_block_size = 0;
has_blockmax = 0;
has_hash_size = 0;
has_hash = 0;
has_prevhash = 0;
@ -2348,6 +2350,14 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
/* LCOV_EXCL_STOP */
}
if (!has_blockmax) {
/* LCOV_EXCL_START */
decoding_error(path, f);
log_fatal(EINTERNAL, "Internal inconsistency: Missing 'blockmax' before file in the content file!\n");
os_abort();
/* LCOV_EXCL_STOP */
}
/* check for impossible file size to avoid to crash for a too big allocation */
if (v_size / state->block_size > blockmax) {
/* LCOV_EXCL_START */
@ -2524,10 +2534,10 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
block_off_t v_pos;
uint64_t v_oldest;
if (has_info) {
if (has_info || !has_blockmax) {
/* LCOV_EXCL_START */
decoding_error(path, f);
log_fatal(EINTERNAL, "Internal inconsistency: Duplicate 'info' in the content file!\n");
log_fatal(EINTERNAL, "Internal inconsistency: Duplicate or misplaced 'info' in the content file!\n");
os_abort();
/* LCOV_EXCL_STOP */
}
@ -2681,6 +2691,14 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
}
disk = tommy_array_get(&disk_mapping, mapping);
if (!has_blockmax) {
/* LCOV_EXCL_START */
decoding_error(path, f);
log_fatal(EINTERNAL, "Internal inconsistency: Missing 'blockmax' before hole in the content file!\n");
os_abort();
/* LCOV_EXCL_STOP */
}
v_pos = 0;
while (v_pos < blockmax) {
block_off_t v_idx;
@ -3181,6 +3199,15 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
/* LCOV_EXCL_STOP */
}
} else if (c == 'x') {
if (has_blockmax || mapping_max != 0) {
/* LCOV_EXCL_START */
decoding_error(path, f);
log_fatal(EINTERNAL, "Internal inconsistency: Duplicate or misplaced 'blockmax' in the content file!\n");
os_abort();
/* LCOV_EXCL_STOP */
}
has_blockmax = 1;
ret = sgetb64(f, &blockmax);
if (ret < 0) {
/* LCOV_EXCL_START */
@ -3617,6 +3644,14 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
/* LCOV_EXCL_STOP */
}
if (!has_blockmax) {
/* LCOV_EXCL_START */
decoding_error(path, f);
log_fatal(EINTERNAL, "Internal inconsistency: Missing 'blockmax' in the content file!\n");
os_abort();
/* LCOV_EXCL_STOP */
}
/* check the file-system on all disks */
state_fscheck(state, "after read");