From: Timo Sirainen Date: Sat, 14 Jan 2023 22:42:39 +0000 (+0200) Subject: global: Make sure memcpy() isn't called with NULL parameters X-Git-Tag: 2.4.0~3015 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1becfd8a2349aed3897dafd3ad6033b61f5759d8;p=thirdparty%2Fdovecot%2Fcore.git global: Make sure memcpy() isn't called with NULL parameters Add an explicit if-check to make sure neither destination nor source pointer parameter is NULL, since it's undefined behavior and can lead to crashes with current compilers. Currently this code isn't known to have caused issues. --- diff --git a/src/lib-fs/fs-api.c b/src/lib-fs/fs-api.c index 09a7439986..4c869625ac 100644 --- a/src/lib-fs/fs-api.c +++ b/src/lib-fs/fs-api.c @@ -689,7 +689,8 @@ ssize_t fs_read_via_stream(struct fs_file *file, void *buf, size_t size) i_stream_get_error(file->pending_read_input)); } else { ret = I_MIN(size, data_size); - memcpy(buf, data, ret); + if (ret > 0) + memcpy(buf, data, ret); } i_stream_unref(&file->pending_read_input); return ret; diff --git a/src/lib-sql/driver-cassandra.c b/src/lib-sql/driver-cassandra.c index 46b5d539c6..e48914c5c6 100644 --- a/src/lib-sql/driver-cassandra.c +++ b/src/lib-sql/driver-cassandra.c @@ -1752,7 +1752,8 @@ driver_cassandra_get_value(struct cassandra_result *result, return -1; } output_dup = p_malloc(result->row_pool, output_size + 1); - memcpy(output_dup, output, output_size); + if (output_size > 0) + memcpy(output_dup, output, output_size); *str_r = output_dup; *len_r = output_size; return 0; diff --git a/src/lib-storage/index/dbox-multi/mdbox-map.c b/src/lib-storage/index/dbox-multi/mdbox-map.c index 978223e64d..309a17ba07 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-map.c +++ b/src/lib-storage/index/dbox-multi/mdbox-map.c @@ -264,7 +264,8 @@ mdbox_map_get_ext_hdr(struct mdbox_map *map, struct mail_index_view *view, mail_index_get_header_ext(view, map->map_ext_id, &data, &data_size); i_zero(hdr_r); - memcpy(hdr_r, data, I_MIN(data_size, sizeof(*hdr_r))); + if (data_size > 0) + memcpy(hdr_r, data, I_MIN(data_size, sizeof(*hdr_r))); } uint32_t mdbox_map_get_rebuild_count(struct mdbox_map *map) diff --git a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c index 3db6be2ff7..b69125f7c5 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c +++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c @@ -495,7 +495,8 @@ mdbox_rebuild_get_header(struct mail_index_view *view, uint32_t hdr_ext_id, mail_index_get_header_ext(view, hdr_ext_id, &data, &data_size); i_zero(hdr_r); - memcpy(hdr_r, data, I_MIN(data_size, sizeof(*hdr_r))); + if (data_size > 0) + memcpy(hdr_r, data, I_MIN(data_size, sizeof(*hdr_r))); *need_resize_r = data_size < sizeof(*hdr_r); } @@ -928,8 +929,10 @@ mdbox_storage_rebuild_scan_prepare(struct mdbox_storage_rebuild_context *ctx) ctx->storage->map->map_ext_id, &data, &data_size); i_zero(&ctx->orig_map_hdr); - memcpy(&ctx->orig_map_hdr, data, - I_MIN(data_size, sizeof(ctx->orig_map_hdr))); + if (data_size > 0) { + memcpy(&ctx->orig_map_hdr, data, + I_MIN(data_size, sizeof(ctx->orig_map_hdr))); + } ctx->highest_file_id = ctx->orig_map_hdr.highest_file_id; /* get storage rebuild counter after locking */ diff --git a/src/lib-storage/index/dbox-single/sdbox-storage.c b/src/lib-storage/index/dbox-single/sdbox-storage.c index 219873ef23..cfa439549d 100644 --- a/src/lib-storage/index/dbox-single/sdbox-storage.c +++ b/src/lib-storage/index/dbox-single/sdbox-storage.c @@ -164,7 +164,8 @@ int sdbox_read_header(struct sdbox_mailbox *mbox, ret = -1; } else { i_zero(hdr); - memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr))); + if (data_size > 0) + memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr))); if (guid_128_is_empty(hdr->mailbox_guid)) ret = -1; else { diff --git a/src/lib/buffer.c b/src/lib/buffer.c index 91123de15b..a6d8fef03e 100644 --- a/src/lib/buffer.c +++ b/src/lib/buffer.c @@ -253,7 +253,7 @@ void buffer_insert(buffer_t *_buf, size_t pos, if (pos >= buf->used) buffer_write(_buf, pos, data, data_size); - else { + else if (data_size > 0) { buffer_copy(_buf, pos + data_size, _buf, pos, SIZE_MAX); memcpy(buf->w_buffer + pos, data, data_size); } diff --git a/src/lib/hmac.c b/src/lib/hmac.c index 0138a4a61a..eb2436a876 100644 --- a/src/lib/hmac.c +++ b/src/lib/hmac.c @@ -35,7 +35,8 @@ void hmac_init(struct hmac_context *_ctx, const unsigned char *key, key_len = meth->digest_size; } - memcpy(k_ipad, key, key_len); + if (key_len > 0) + memcpy(k_ipad, key, key_len); memset(k_ipad + key_len, 0, meth->block_size - key_len); memcpy(k_opad, k_ipad, meth->block_size); diff --git a/src/lib/istream-concat.c b/src/lib/istream-concat.c index 4c58b8653f..253edd6f60 100644 --- a/src/lib/istream-concat.c +++ b/src/lib/istream-concat.c @@ -108,8 +108,10 @@ static void i_stream_concat_read_next(struct concat_istream *cstream) } cstream->prev_stream_left = data_size; - memcpy(cstream->istream.w_buffer, data, data_size); - i_stream_skip(prev_input, data_size); + if (data_size > 0) { + memcpy(cstream->istream.w_buffer, data, data_size); + i_stream_skip(prev_input, data_size); + } cstream->istream.skip = 0; cstream->istream.pos = data_size; } diff --git a/src/lib/istream.c b/src/lib/istream.c index 435589a754..5fabe1e3f4 100644 --- a/src/lib/istream.c +++ b/src/lib/istream.c @@ -987,6 +987,8 @@ bool i_stream_add_data(struct istream *_stream, const unsigned char *data, struct istream_private *stream = _stream->real_stream; size_t size2; + if (size == 0) + return TRUE; (void)i_stream_try_alloc(stream, size, &size2); if (size > size2) return FALSE; diff --git a/src/lib/md4.c b/src/lib/md4.c index 06e3231bde..06082f53c7 100644 --- a/src/lib/md4.c +++ b/src/lib/md4.c @@ -181,6 +181,9 @@ void md4_update(struct md4_context *ctx, const void *data, size_t size) uint_fast32_t saved_lo; unsigned long used, free; + if (size == 0) + return; + saved_lo = ctx->lo; if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) ctx->hi++; diff --git a/src/lib/md5.c b/src/lib/md5.c index 6b5da6c307..46cffb6d12 100644 --- a/src/lib/md5.c +++ b/src/lib/md5.c @@ -195,6 +195,9 @@ md5_update(struct md5_context *ctx, const void *data, size_t size) uint_fast32_t saved_lo; unsigned long used, free; + if (size == 0) + return; + saved_lo = ctx->lo; if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) ctx->hi++; diff --git a/src/lib/mempool-alloconly.c b/src/lib/mempool-alloconly.c index 42b9ff2fa2..a9e8cd701a 100644 --- a/src/lib/mempool-alloconly.c +++ b/src/lib/mempool-alloconly.c @@ -475,7 +475,8 @@ static void *pool_alloconly_realloc(pool_t pool, void *mem, if (!pool_alloconly_try_grow(apool, mem, new_size)) { /* slow way - allocate + copy */ new_mem = pool_alloconly_malloc(pool, new_size); - memcpy(new_mem, mem, old_size); + if (old_size > 0) + memcpy(new_mem, mem, old_size); mem = new_mem; } diff --git a/src/lib/mempool-datastack.c b/src/lib/mempool-datastack.c index b3c1094bf0..6905f9592e 100644 --- a/src/lib/mempool-datastack.c +++ b/src/lib/mempool-datastack.c @@ -171,7 +171,8 @@ static void *pool_data_stack_realloc(pool_t pool, void *mem, if (!t_try_realloc(mem, new_size)) { new_mem = t_malloc_no0(new_size); - memcpy(new_mem, mem, old_size); + if (old_size > 0) + memcpy(new_mem, mem, old_size); mem = new_mem; } diff --git a/src/lib/mempool-unsafe-datastack.c b/src/lib/mempool-unsafe-datastack.c index 2f2751ddc8..394fdeb6a1 100644 --- a/src/lib/mempool-unsafe-datastack.c +++ b/src/lib/mempool-unsafe-datastack.c @@ -116,7 +116,8 @@ static void *pool_unsafe_data_stack_realloc(pool_t pool ATTR_UNUSED, if (!t_try_realloc(mem, new_size)) { new_mem = t_malloc_no0(new_size); - memcpy(new_mem, mem, old_size); + if (old_size > 0) + memcpy(new_mem, mem, old_size); mem = new_mem; } diff --git a/src/lib/sha2.c b/src/lib/sha2.c index 93dddfbb39..552ac24e76 100644 --- a/src/lib/sha2.c +++ b/src/lib/sha2.c @@ -257,6 +257,9 @@ void sha256_loop(struct sha256_ctx *ctx, const void *data, size_t block_nb; size_t new_len, rem_len, tmp_len; + if (len == 0) + return; + tmp_len = SHA256_BLOCK_SIZE - ctx->len; rem_len = len < tmp_len ? len : tmp_len; @@ -384,6 +387,9 @@ void sha384_loop(struct sha384_ctx *ctx, const void *data, size_t block_nb; size_t new_len, rem_len, tmp_len; + if (len == 0) + return; + tmp_len = SHA384_BLOCK_SIZE - ctx->len; rem_len = len < tmp_len ? len : tmp_len; @@ -511,6 +517,9 @@ void sha512_loop(struct sha512_ctx *ctx, const void *data, size_t block_nb; size_t new_len, rem_len, tmp_len; + if (len == 0) + return; + tmp_len = SHA512_BLOCK_SIZE - ctx->len; rem_len = len < tmp_len ? len : tmp_len;