diff --git a/cmdline/check.c b/cmdline/check.c index f13639ec..70cf88c9 100644 --- a/cmdline/check.c +++ b/cmdline/check.c @@ -975,8 +975,8 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna memset(buffer[buffermax - 1], 0, state->block_size); raid_zero(buffer[buffermax - 1]); - failed = malloc_nofail(diskmax * sizeof(struct failed_struct)); - failed_map = malloc_nofail(diskmax * sizeof(unsigned)); + failed = nalloc_nofail(diskmax, sizeof(struct failed_struct)); + failed_map = nalloc_nofail(diskmax, sizeof(unsigned)); soft_error = 0; io_error = 0; diff --git a/cmdline/dry.c b/cmdline/dry.c index 0063887a..8ea55991 100644 --- a/cmdline/dry.c +++ b/cmdline/dry.c @@ -171,7 +171,7 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit /* possibly waiting disks */ waiting_mac = diskmax > RAID_PARITY_MAX ? diskmax : RAID_PARITY_MAX; - waiting_map = malloc_nofail(waiting_mac * sizeof(unsigned)); + waiting_map = nalloc_nofail(waiting_mac, sizeof(unsigned)); soft_error = 0; io_error = 0; diff --git a/cmdline/dup.c b/cmdline/dup.c index 5c88cb11..873be3f8 100644 --- a/cmdline/dup.c +++ b/cmdline/dup.c @@ -33,7 +33,7 @@ struct snapraid_hash* hash_alloc(struct snapraid_state* state, struct snapraid_d hash->disk = disk; hash->file = file; - buf = malloc_nofail(file->blockmax * hash_size); + buf = nalloc_nofail(file->blockmax, hash_size); /* set the back pointer */ for (i = 0; i < file->blockmax; ++i) { diff --git a/cmdline/elem.c b/cmdline/elem.c index 7e86b99b..21686120 100644 --- a/cmdline/elem.c +++ b/cmdline/elem.c @@ -412,7 +412,7 @@ struct snapraid_file* file_alloc(unsigned block_size, const char* sub, data_off_ file->physical = physical; file->flag = 0; file->shared_flag = 0; - file->blockvec = malloc_nofail(file->blockmax * block_sizeof()); + file->blockvec = nalloc_nofail(file->blockmax, block_sizeof()); for (i = 0; i < file->blockmax; ++i) { struct snapraid_block* block = file_block(file, i); @@ -437,7 +437,7 @@ struct snapraid_file* file_dup(struct snapraid_file* copy) file->inode = copy->inode; file->physical = copy->physical; file->flag = copy->flag; - file->blockvec = malloc_nofail(file->blockmax * block_sizeof()); + file->blockvec = nalloc_nofail(file->blockmax, block_sizeof()); for (i = 0; i < file->blockmax; ++i) { struct snapraid_block* block = file_block(file, i); @@ -781,7 +781,7 @@ struct snapraid_dealloc* dealloc_alloc(unsigned block_size, const char* sub, dat dealloc->mtime_sec = mtime_sec; dealloc->mtime_nsec = mtime_nsec; dealloc->blockmax = (size + block_size - 1) / block_size; - dealloc->blockhash = malloc_nofail(dealloc->blockmax * BLOCK_HASH_SIZE); + dealloc->blockhash = nalloc_nofail(dealloc->blockmax, BLOCK_HASH_SIZE); return dealloc; } diff --git a/cmdline/handle.c b/cmdline/handle.c index 9a979d0e..34bba9f3 100644 --- a/cmdline/handle.c +++ b/cmdline/handle.c @@ -382,7 +382,7 @@ struct snapraid_handle* handle_mapping(struct snapraid_state* state, unsigned* h } ++size; /* size is one more than the max */ - handle = malloc_nofail(size * sizeof(struct snapraid_handle)); + handle = nalloc_nofail(size, sizeof(struct snapraid_handle)); for (j = 0; j < size; ++j) { /* default for empty position */ diff --git a/cmdline/import.c b/cmdline/import.c index 931f6b02..64476668 100644 --- a/cmdline/import.c +++ b/cmdline/import.c @@ -54,7 +54,7 @@ static void import_file(struct snapraid_state* state, const char* path, uint64_t file->path = strdup_nofail(path); file->size = size; file->blockmax = (size + block_size - 1) / block_size; - file->blockimp = malloc_nofail(file->blockmax * sizeof(struct snapraid_import_block)); + file->blockimp = nalloc_nofail(file->blockmax, sizeof(struct snapraid_import_block)); file->is_runtime = 1; buffer = malloc_nofail(block_size); @@ -144,7 +144,7 @@ static void import_dealloc(struct snapraid_state* state, const char* dir, struct file->path = strdup_nofail(path); file->size = size; file->blockmax = (size + block_size - 1) / block_size; - file->blockimp = malloc_nofail(file->blockmax * sizeof(struct snapraid_import_block)); + file->blockimp = nalloc_nofail(file->blockmax, sizeof(struct snapraid_import_block)); file->is_runtime = 0; offset = 0; diff --git a/cmdline/io.c b/cmdline/io.c index de4d2c2a..56d7ba57 100644 --- a/cmdline/io.c +++ b/cmdline/io.c @@ -1021,10 +1021,10 @@ void io_init(struct snapraid_io* io, struct snapraid_state* state, io->reader_max = readers_count; io->writer_max = writers_count; - io->reader_map = malloc_nofail(sizeof(struct snapraid_worker) * io->reader_max); - io->reader_list = malloc_nofail(sizeof(unsigned) * (io->reader_max + 1)); - io->writer_map = malloc_nofail(sizeof(struct snapraid_worker) * io->writer_max); - io->writer_list = malloc_nofail(sizeof(unsigned) * (io->writer_max + 1)); + io->reader_map = nalloc_nofail(io->reader_max, sizeof(struct snapraid_worker)); + io->reader_list = nalloc_nofail(io->reader_max + 1, sizeof(unsigned)); + io->writer_map = nalloc_nofail(io->writer_max, sizeof(struct snapraid_worker)); + io->writer_list = nalloc_nofail(io->writer_max + 1, sizeof(unsigned)); io->data_base = 0; io->data_count = 0; diff --git a/cmdline/scrub.c b/cmdline/scrub.c index 093c9d95..5c536745 100644 --- a/cmdline/scrub.c +++ b/cmdline/scrub.c @@ -275,7 +275,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par /* possibly waiting disks */ waiting_mac = diskmax > RAID_PARITY_MAX ? diskmax : RAID_PARITY_MAX; - waiting_map = malloc_nofail(waiting_mac * sizeof(unsigned)); + waiting_map = nalloc_nofail(waiting_mac, sizeof(unsigned)); soft_error = 0; silent_error = 0; diff --git a/cmdline/stream.c b/cmdline/stream.c index aa382107..bb1256d7 100644 --- a/cmdline/stream.c +++ b/cmdline/stream.c @@ -91,7 +91,7 @@ STREAM* sopen_multi_write(unsigned count, int flags) STREAM* s = malloc_nofail(sizeof(STREAM)); s->handle_size = count; - s->handle = malloc_nofail(count * sizeof(struct stream_handle)); + s->handle = nalloc_nofail(count, sizeof(struct stream_handle)); s->flags = flags; for (i = 0; i < count; ++i) diff --git a/cmdline/support.c b/cmdline/support.c index 85a89cdd..70aaa4ca 100644 --- a/cmdline/support.c +++ b/cmdline/support.c @@ -2211,14 +2211,17 @@ void* malloc_nofail(size_t size) return ptr; } -void* calloc_nofail(size_t count, size_t size) +void* nalloc_nofail(size_t count, size_t size) { - void* ptr; + if (count > SIZE_MAX / size) { + log_fatal(EINTERNAL, "Allocation size overflow\n"); + os_abort(); + } size *= count; /* see the note in malloc_nofail() of why we don't use calloc() */ - ptr = malloc(size ? size : 1); + void* ptr = malloc(size ? size : 1); if (!ptr) { /* LCOV_EXCL_START */ @@ -2227,33 +2230,28 @@ void* calloc_nofail(size_t count, size_t size) /* LCOV_EXCL_STOP */ } - memset(ptr, 0, size); - malloc_counter_inc(size); return ptr; } +void* calloc_nofail(size_t count, size_t size) +{ + void* ptr = nalloc_nofail(count, size); + + memset(ptr, 0, count * size); + + return ptr; +} + char* strdup_nofail(const char* str) { - size_t size; - char* ptr; + size_t size = strlen(str) + 1; - size = strlen(str) + 1; - - ptr = malloc(size); - - if (!ptr) { - /* LCOV_EXCL_START */ - malloc_fail(size); - exit(EXIT_FAILURE); - /* LCOV_EXCL_STOP */ - } + char* ptr = malloc_nofail(size); memcpy(ptr, str, size); - malloc_counter_inc(size); - return ptr; } diff --git a/cmdline/support.h b/cmdline/support.h index 9900a6e1..93463db9 100644 --- a/cmdline/support.h +++ b/cmdline/support.h @@ -534,7 +534,13 @@ size_t malloc_counter_get(void); void* malloc_nofail(size_t size); /** - * Safe cmalloc. + * Safe malloc with calloc calling arguments. + * If no memory is available, it aborts. + */ +void* nalloc_nofail(size_t count, size_t size); + +/** + * Safe calloc. * If no memory is available, it aborts. */ void* calloc_nofail(size_t count, size_t size); diff --git a/cmdline/sync.c b/cmdline/sync.c index b8f34f87..e5f16631 100644 --- a/cmdline/sync.c +++ b/cmdline/sync.c @@ -693,12 +693,12 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari memset(zero, 0, state->block_size); raid_zero(zero); - failed = malloc_nofail(diskmax * sizeof(struct failed_struct)); - failed_map = malloc_nofail(diskmax * sizeof(unsigned)); + failed = nalloc_nofail(diskmax, sizeof(struct failed_struct)); + failed_map = nalloc_nofail(diskmax, sizeof(unsigned)); /* possibly waiting disks */ waiting_mac = diskmax > RAID_PARITY_MAX ? diskmax : RAID_PARITY_MAX; - waiting_map = malloc_nofail(waiting_mac * sizeof(unsigned)); + waiting_map = nalloc_nofail(waiting_mac, sizeof(unsigned)); soft_error = 0; silent_error = 0;