From b35c4185586fc059d32a4885a3b056dd0a336c6d Mon Sep 17 00:00:00 2001 From: TuxSH Date: Thu, 8 Mar 2018 11:17:46 +0100 Subject: [PATCH] memcpy(x, NULL, 0) is undefined behavior --- exosphere/src/i2c.c | 8 +++++++- exosphere/src/package2.c | 4 ++-- exosphere/src/randomcache.c | 6 ++++-- exosphere/src/se.c | 9 ++++++--- exosphere/src/smc_user.c | 4 +++- exosphere/src/titlekey.c | 5 +++-- exosphere/src/userpage.c | 8 ++++++-- 7 files changed, 31 insertions(+), 13 deletions(-) diff --git a/exosphere/src/i2c.c b/exosphere/src/i2c.c index d98700859..8dc0ee88a 100644 --- a/exosphere/src/i2c.c +++ b/exosphere/src/i2c.c @@ -131,7 +131,9 @@ bool i2c_query(unsigned int id, uint8_t device, uint8_t r, void *dst, size_t dst /* Writes a value to a register over I2C. */ bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_size) { uint32_t val = r; - if (src_size <= 3) { + if (src_size == 0) { + return true; + } else if (src_size <= 3) { memcpy(((uint8_t *)&val) + 1, src, src_size); return i2c_write(i2c_get_registers_from_id(id), device, &val, src_size + 1); } else { @@ -143,6 +145,8 @@ bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_ bool i2c_write(volatile i2c_registers_t *regs, uint8_t device, void *src, size_t src_size) { if (src_size > 4) { return false; + } else if (src_size == 0) { + return true; } /* Set device for 7-bit write mode. */ @@ -172,6 +176,8 @@ bool i2c_write(volatile i2c_registers_t *regs, uint8_t device, void *src, size_t bool i2c_read(volatile i2c_registers_t *regs, uint8_t device, void *dst, size_t dst_size) { if (dst_size > 4) { return false; + } else if (dst_size == 0) { + return true; } /* Set device for 7-bit read mode. */ diff --git a/exosphere/src/package2.c b/exosphere/src/package2.c index b0c0f4ee6..0c37d8a9e 100644 --- a/exosphere/src/package2.c +++ b/exosphere/src/package2.c @@ -323,9 +323,9 @@ static void load_package2_sections(package2_meta_t *metadata, uint32_t master_ke void *src_start = load_buf + sizeof(package2_header_t) + cur_section_offset; size_t size = (size_t)metadata->section_sizes[section]; - if (bootconfig_is_package2_plaintext()) { + if (bootconfig_is_package2_plaintext() && size != 0) { memcpy(dst_start, src_start, size); - } else { + } else if (size != 0) { package2_crypt_ctr(master_key_rev, dst_start, size, src_start, size, metadata->section_ctrs[section], 0x10); } cur_section_offset += size; diff --git a/exosphere/src/randomcache.c b/exosphere/src/randomcache.c index e21ffd9ee..88dcbb4fc 100644 --- a/exosphere/src/randomcache.c +++ b/exosphere/src/randomcache.c @@ -61,13 +61,15 @@ void randomcache_refill(void) { void randomcache_getbytes(void *dst, size_t num_bytes) { unsigned int low = g_random_cache_low; - + if (num_bytes == 0) { + return; + } memcpy(dst, &g_random_cache[low], num_bytes); unsigned int new_low = low + num_bytes; if (new_low + 0x38 > 0x3FF) { new_low = 0; } - + g_random_cache_low = new_low; } diff --git a/exosphere/src/se.c b/exosphere/src/se.c index a64d6d45d..e7b7401b5 100644 --- a/exosphere/src/se.c +++ b/exosphere/src/se.c @@ -476,7 +476,9 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, } /* Load src data into block. */ - memcpy(block, src, src_size); + if (src_size != 0) { + memcpy(block, src, src_size); + } flush_dcache_range(block, block + sizeof(block)); /* Trigger AES operation. */ @@ -485,7 +487,9 @@ void se_perform_aes_block_operation(void *dst, size_t dst_size, const void *src, /* Copy output data into dst. */ flush_dcache_range(block, block + sizeof(block)); - memcpy(dst, block, dst_size); + if (dst_size != 0) { + memcpy(dst, block, dst_size); + } } void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size) { @@ -602,7 +606,6 @@ void se_compute_aes_cmac(unsigned int keyslot, void *cmac, size_t cmac_size, con uint8_t last_block[0x10]; memset(last_block, 0, sizeof(last_block)); if (data_size & 0xF) { - memcpy(last_block, data + (data_size & ~0xF), data_size & 0xF); last_block[data_size & 0xF] = 0x80; /* Last block = data || 100...0 */ } else if (data_size >= 0x10) { diff --git a/exosphere/src/smc_user.c b/exosphere/src/smc_user.c index f6f669d2a..ff6a4034e 100644 --- a/exosphere/src/smc_user.c +++ b/exosphere/src/smc_user.c @@ -91,7 +91,9 @@ uint32_t user_get_random_bytes(smc_args_t *args) { se_generate_random(KEYSLOT_SWITCH_RNGKEY, random_bytes, size); flush_dcache_range(random_bytes, random_bytes + size); - memcpy(&args->X[1], random_bytes, size); + if (size != 0) { + memcpy(&args->X[1], random_bytes, size); + } return 0; } diff --git a/exosphere/src/titlekey.c b/exosphere/src/titlekey.c index ec5b96e8c..0c5cb7cf1 100644 --- a/exosphere/src/titlekey.c +++ b/exosphere/src/titlekey.c @@ -34,8 +34,9 @@ void calculate_mgf1_and_xor(void *masked, size_t masked_size, const void *seed, } size_t hash_buf_size = seed_size + 4; - memcpy(hash_buf, seed, seed_size); - + if (seed_size != 0) { + memcpy(hash_buf, seed, seed_size); + } uint32_t round_num = 0; uint8_t *p_out = (uint8_t *)masked; diff --git a/exosphere/src/userpage.c b/exosphere/src/userpage.c index 1a4b4dadb..d09c57157 100644 --- a/exosphere/src/userpage.c +++ b/exosphere/src/userpage.c @@ -50,7 +50,9 @@ bool user_copy_to_secure(upage_ref_t *upage, void *secure_dst, void *user_src, s } void *secure_src = (void *)(upage->secure_monitor_address + ((uintptr_t)user_src - upage->user_address)); - memcpy(secure_dst, secure_src, size); + if (size != 0) { + memcpy(secure_dst, secure_src, size); + } return true; } @@ -66,6 +68,8 @@ bool secure_copy_to_user(upage_ref_t *upage, void *user_dst, void *secure_src, s } void *secure_dst = (void *)(upage->secure_monitor_address + ((uintptr_t)user_dst - upage->user_address)); - memcpy(secure_dst, secure_src, size); + if(size != 0) { + memcpy(secure_dst, secure_src, size); + } return true; }