From bcc06e10c6393108fee56abf514ad8eb31fc4b56 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Thu, 24 Sep 2026 20:40:27 +0200 Subject: [PATCH] Reject parity sizes exceeding data_off_t range and remove redundant block size casts --- cmdline/check.c | 2 +- cmdline/handle.c | 4 ++-- cmdline/parity.c | 9 +++++++-- cmdline/search.c | 2 +- cmdline/state.c | 2 +- cmdline/sync.c | 4 ++-- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/cmdline/check.c b/cmdline/check.c index 9795a2d7..bf209a15 100644 --- a/cmdline/check.c +++ b/cmdline/check.c @@ -3087,7 +3087,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b */ blockmax = parity_allocated_size(state); - size = blockmax * (data_off_t)state->block_size; + size = blockmax * state->block_size; if (blockstart > blockmax) { /* LCOV_EXCL_START */ diff --git a/cmdline/handle.c b/cmdline/handle.c index d721f045..e532fb53 100644 --- a/cmdline/handle.c +++ b/cmdline/handle.c @@ -375,7 +375,7 @@ ssize_t handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsign unsigned count; int ret; - offset = file_pos * (data_off_t)block_size; + offset = file_pos * block_size; if (!out_missing) out_missing = log_error; @@ -456,7 +456,7 @@ int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned /* LCOV_EXCL_STOP */ } - offset = file_pos * (data_off_t)block_size; + offset = file_pos * block_size; write_size = file_block_size(handle->file, file_pos, block_size); diff --git a/cmdline/parity.c b/cmdline/parity.c index 09b9b4d7..c3e7dadc 100644 --- a/cmdline/parity.c +++ b/cmdline/parity.c @@ -44,6 +44,11 @@ block_off_t parity_allocated_size(struct snapraid_state* state) parity_block = block; } + if (parity_block > (block_off_t)INT64_MAX / state->block_size) { + log_fatal(ESOFT, "Parity with %" PRIu64 " blocks is too large for block size %u.\n", parity_block, state->block_size); + exit(EXIT_FAILURE); + } + return parity_block; } @@ -1083,7 +1088,7 @@ int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigne unsigned count; int ret; - offset = pos * (data_off_t)block_size; + offset = pos * block_size; split = parity_split_find(handle, &offset); if (!split) { @@ -1177,7 +1182,7 @@ int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned struct snapraid_split_handle* split; int ret; - offset = pos * (data_off_t)block_size; + offset = pos * block_size; split = parity_split_find(handle, &offset); if (!split) { diff --git a/cmdline/search.c b/cmdline/search.c index ed9a6583..de65001c 100644 --- a/cmdline/search.c +++ b/cmdline/search.c @@ -137,7 +137,7 @@ int state_search_fetch(struct snapraid_state* state, int prevhash, struct snapra arg.block = missing_block; arg.file = missing_file; arg.buffer = buffer; - arg.offset = state->block_size * (data_off_t)missing_file_pos; + arg.offset = state->block_size * missing_file_pos; arg.read_size = file_block_size(missing_file, missing_file_pos, state->block_size); arg.prevhash = prevhash; diff --git a/cmdline/state.c b/cmdline/state.c index 976dce98..bed83c95 100644 --- a/cmdline/state.c +++ b/cmdline/state.c @@ -2950,7 +2950,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S * Allocate without initializing blocks. This deleted run sets every * state and hash before the file is inserted in the extent map. */ - deleted = file_alloc(state->block_size, "", v_count * (data_off_t)state->block_size, 0, 0, 0); + deleted = file_alloc(state->block_size, "", v_count * state->block_size, 0, 0, 0); /* mark the file as deleted */ file_flag_set(deleted, FILE_IS_DELETED); diff --git a/cmdline/sync.c b/cmdline/sync.c index fda79533..c7dd36d0 100644 --- a/cmdline/sync.c +++ b/cmdline/sync.c @@ -2019,11 +2019,11 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t * but must not be shorter than used_size (which indicates missing parity). */ blockmax = parity_allocated_size(state); - size = blockmax * (data_off_t)state->block_size; + size = blockmax * state->block_size; /* minimum size of the parity files we expect */ used_paritymax = parity_used_size(state); - used_parity_size = used_paritymax * (data_off_t)state->block_size; + used_parity_size = used_paritymax * state->block_size; if (blockstart > blockmax) { /* LCOV_EXCL_START */