mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 10:51:54 -04:00
Add protection for block position integer overflow
This commit is contained in:
parent
c814b474be
commit
cc99a22929
5 changed files with 25 additions and 17 deletions
|
|
@ -2092,7 +2092,7 @@ int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, b
|
|||
}
|
||||
|
||||
/* adjust the number of block to process */
|
||||
if (blockcount != 0 && blockstart + blockcount < blockmax) {
|
||||
if (blockcount != 0 && blockcount < blockmax - blockstart) {
|
||||
blockmax = blockstart + blockcount;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -433,7 +433,7 @@ int state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
}
|
||||
|
||||
/* adjust the number of block to process */
|
||||
if (blockcount != 0 && blockstart + blockcount < blockmax) {
|
||||
if (blockcount != 0 && blockcount < blockmax - blockstart) {
|
||||
blockmax = blockstart + blockcount;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -634,7 +634,7 @@ struct snapraid_extent* extent_alloc(block_off_t parity_pos, struct snapraid_fil
|
|||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (file_pos + count > file->blockmax) {
|
||||
if (count > file->blockmax || file_pos > file->blockmax - count) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EINTERNAL, "Internal inconsistency: Allocating overflowing extent for file '%s' at position '%u:%u/%u'\n", file->sub, file_pos, count, file->blockmax);
|
||||
os_abort();
|
||||
|
|
@ -995,7 +995,7 @@ static void extent_parity_check_foreach_unlock(void* void_arg, void* void_obj)
|
|||
}
|
||||
|
||||
/* check that the extents don't overlap */
|
||||
if (prev->parity_pos + prev->count > obj->parity_pos) {
|
||||
if (obj->parity_pos - prev->parity_pos < prev->count) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EINTERNAL, "Internal inconsistency: Parity overlap for files '%s' at '%u:%u' and '%s' at '%u:%u'\n",
|
||||
prev->file->sub, prev->parity_pos, prev->count, obj->file->sub, obj->parity_pos, obj->count);
|
||||
|
|
@ -1037,7 +1037,7 @@ static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
|
|||
if (prev != 0) {
|
||||
if (file_flag_has(prev->file, FILE_IS_DELETED)) {
|
||||
/* check that the extent doesn't overflow the file */
|
||||
if (prev->file_pos + prev->count > prev->file->blockmax) {
|
||||
if (prev->count > prev->file->blockmax || prev->file_pos > prev->file->blockmax - prev->count) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EINTERNAL, "Internal inconsistency: Delete end for file '%s' at '%u:%u' overflowing size '%u'\n",
|
||||
prev->file->sub, prev->file_pos, prev->count, prev->file->blockmax);
|
||||
|
|
@ -1060,7 +1060,7 @@ static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
|
|||
|
||||
if (file_flag_has(obj->file, FILE_IS_DELETED)) {
|
||||
/* check that the extent doesn't overflow the file */
|
||||
if (obj->file_pos + obj->count > obj->file->blockmax) {
|
||||
if (obj->count > obj->file->blockmax || obj->file_pos > obj->file->blockmax - obj->count) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EINTERNAL, "Internal inconsistency: Delete start for file '%s' at '%u:%u' overflowing size '%u'\n",
|
||||
obj->file->sub, obj->file_pos, obj->count, obj->file->blockmax);
|
||||
|
|
@ -1092,7 +1092,7 @@ static void extent_file_check_foreach_unlock(void* void_arg, void* void_obj)
|
|||
|
||||
if (file_flag_has(obj->file, FILE_IS_DELETED)) {
|
||||
/* check that the extents don't overlap */
|
||||
if (prev->file_pos + prev->count > obj->file_pos) {
|
||||
if (obj->file_pos - prev->file_pos < prev->count) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EINTERNAL, "Internal inconsistency: Delete sequence for file '%s' at '%u:%u' and at '%u:%u'\n",
|
||||
prev->file->sub, prev->file_pos, prev->count, obj->file_pos, obj->count);
|
||||
|
|
@ -1153,7 +1153,7 @@ static int extent_parity_inside_compare_unlock(const void* void_a, const void* v
|
|||
|
||||
if (arg_a->parity_pos < arg_b->parity_pos)
|
||||
return -1;
|
||||
if (arg_a->parity_pos >= arg_b->parity_pos + arg_b->count)
|
||||
if (arg_a->parity_pos - arg_b->parity_pos >= arg_b->count)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
|
@ -1171,7 +1171,7 @@ static struct snapraid_extent* fs_par2extent_get_unlock(struct snapraid_disk* di
|
|||
/* check if the last accessed extent matches */
|
||||
if (*fs_last
|
||||
&& parity_pos >= (*fs_last)->parity_pos
|
||||
&& parity_pos < (*fs_last)->parity_pos + (*fs_last)->count
|
||||
&& parity_pos - (*fs_last)->parity_pos < (*fs_last)->count
|
||||
) {
|
||||
extent = *fs_last;
|
||||
} else {
|
||||
|
|
@ -1208,7 +1208,7 @@ static int extent_file_inside_compare_unlock(const void* void_a, const void* voi
|
|||
|
||||
if (arg_a->file_pos < arg_b->file_pos)
|
||||
return -1;
|
||||
if (arg_a->file_pos >= arg_b->file_pos + arg_b->count)
|
||||
if (arg_a->file_pos - arg_b->file_pos >= arg_b->count)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
|
@ -1227,7 +1227,7 @@ static struct snapraid_extent* fs_file2extent_get_unlock(struct snapraid_disk* d
|
|||
if (*fs_last
|
||||
&& file == (*fs_last)->file
|
||||
&& file_pos >= (*fs_last)->file_pos
|
||||
&& file_pos < (*fs_last)->file_pos + (*fs_last)->count
|
||||
&& file_pos - (*fs_last)->file_pos < (*fs_last)->count
|
||||
) {
|
||||
extent = *fs_last;
|
||||
} else {
|
||||
|
|
@ -1299,6 +1299,14 @@ void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snap
|
|||
extent = fs_file2extent_get_unlock(disk, &disk->fs_last, file, file_pos - 1);
|
||||
|
||||
if (extent != 0 && parity_pos == extent->parity_pos + extent->count) {
|
||||
/* check if the position will go outside the limit */
|
||||
if (extent->parity_pos + extent->count == POS_NULL) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EINTERNAL, "Internal inconsistency: Parity position overflow allocating file '%s' at position '%u/%u' with count '%u' in disk '%s'\n", file->sub, file_pos, file->blockmax, extent->count, disk->name);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* ensure that we are extending the extent at the end */
|
||||
if (file_pos != extent->file_pos + extent->count) {
|
||||
/* LCOV_EXCL_START */
|
||||
|
|
|
|||
|
|
@ -2293,7 +2293,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (v_idx + v_count > file->blockmax) {
|
||||
if (v_count > file->blockmax || v_idx > file->blockmax - v_count) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal(EINTERNAL, "Internal inconsistency: Block number out of range\n");
|
||||
|
|
@ -2301,12 +2301,12 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (v_pos + v_count > blockmax) {
|
||||
if (v_count > blockmax || v_pos > blockmax - v_count) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal(EINTERNAL, "Internal inconsistency: Block size %u/%u!\n", blockmax, v_pos + v_count);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_START */
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* fill the blocks in the run */
|
||||
|
|
@ -2416,7 +2416,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (v_pos + v_count > blockmax) {
|
||||
if (v_count > blockmax || v_pos > blockmax - v_count) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal(EINTERNAL, "Internal inconsistency: Info size %u/%u!\n", blockmax, v_pos + v_count);
|
||||
|
|
@ -2526,7 +2526,7 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (v_pos + v_count > blockmax) {
|
||||
if (v_count > blockmax || v_pos > blockmax - v_count) {
|
||||
/* LCOV_EXCL_START */
|
||||
decoding_error(path, f);
|
||||
log_fatal(EINTERNAL, "Internal inconsistency: Hole size %u/%u!\n", blockmax, v_pos + v_count);
|
||||
|
|
|
|||
|
|
@ -1454,7 +1454,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
|||
}
|
||||
|
||||
/* adjust the number of block to process */
|
||||
if (blockcount != 0 && blockstart + blockcount < blockmax) {
|
||||
if (blockcount != 0 && blockcount < blockmax - blockstart) {
|
||||
blockmax = blockstart + blockcount;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue