Structs alignment in memory, fixes device freezes/crashes

This commit is contained in:
Alexandre Paillier
2022-05-05 15:21:39 +02:00
parent d43849d852
commit 5c00a5c27b
5 changed files with 44 additions and 14 deletions

View File

@@ -3,6 +3,7 @@
#include "encode_field.h" #include "encode_field.h"
#include "path.h" #include "path.h"
#include "mem.h" #include "mem.h"
#include "mem_utils.h"
#include "eip712.h" #include "eip712.h"
#include "shared_context.h" #include "shared_context.h"
@@ -12,7 +13,7 @@ bool field_hash_init(void)
{ {
if (fh == NULL) if (fh == NULL)
{ {
if ((fh = mem_alloc(sizeof(*fh))) == NULL) if ((fh = MEM_ALLOC_AND_ALIGN_TO_TYPE(sizeof(*fh), *fh)) == NULL)
{ {
return false; return false;
} }
@@ -36,7 +37,6 @@ bool field_hash(const uint8_t *data,
#endif #endif
(void)data;
if (fh == NULL) if (fh == NULL)
{ {
return false; return false;

View File

@@ -26,10 +26,9 @@ char *mem_alloc_and_copy_char(char c)
* @param[in] value Value to write in memory * @param[in] value Value to write in memory
* @param[out] length number of characters written to memory * @param[out] length number of characters written to memory
* *
* @return pointer to memory area or \ref NULL if the allocated failed * @return pointer to memory area or \ref NULL if the allocation failed
*/ */
char *mem_alloc_and_format_uint(uint32_t value, char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const length)
uint8_t *const length)
{ {
char *mem_ptr; char *mem_ptr;
uint32_t value_copy; uint32_t value_copy;
@@ -55,3 +54,26 @@ char *mem_alloc_and_format_uint(uint32_t value,
} }
return mem_ptr; return mem_ptr;
} }
/**
* Allocate and align, required when dealing with pointers of multi-bytes data
* like structures that will be dereferenced at runtime.
*
* @param[in] size the size of the data we want to allocate in memory
* @param[in] alignment the byte alignment needed
*
* @return pointer to the memory area, \ref NULL if the allocation failed
*/
void *mem_alloc_and_align(size_t size, size_t alignment)
{
uint8_t align_diff = (uintptr_t)mem_alloc(0) % alignment;
if (align_diff > 0) // alignment needed
{
if (mem_alloc(alignment - align_diff) == NULL)
{
return NULL;
}
}
return mem_alloc(size);
}

View File

@@ -4,9 +4,11 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#define MEM_ALLOC_AND_ALIGN_TO_TYPE(size, type) (mem_alloc_and_align(size, __alignof__(type)))
char *mem_alloc_and_copy_char(char c); char *mem_alloc_and_copy_char(char c);
void *mem_alloc_and_copy(const void *data, size_t size); void *mem_alloc_and_copy(const void *data, size_t size);
char *mem_alloc_and_format_uint(uint32_t value, char *mem_alloc_and_format_uint(uint32_t value, uint8_t *const written_chars);
uint8_t *const written_chars); void *mem_alloc_and_align(size_t size, size_t alignment);
#endif // MEM_UTILS_H_ #endif // MEM_UTILS_H_

View File

@@ -7,6 +7,7 @@
#include "type_hash.h" #include "type_hash.h"
#include "shared_context.h" #include "shared_context.h"
#include "ethUtils.h" #include "ethUtils.h"
#include "mem_utils.h"
static s_path *path_struct = NULL; static s_path *path_struct = NULL;
@@ -255,7 +256,7 @@ static bool path_update(void)
const uint8_t *thash_ptr; const uint8_t *thash_ptr;
// allocate new hash context // allocate new hash context
if ((hash_ctx = mem_alloc(sizeof(cx_sha3_t))) == NULL) if ((hash_ctx = mem_alloc(sizeof(*hash_ctx))) == NULL)
{ {
return false; return false;
} }
@@ -304,7 +305,7 @@ bool path_set_root(const char *const struct_name, uint8_t name_length)
// TODO: Move elsewhere // TODO: Move elsewhere
cx_sha3_t *hash_ctx; cx_sha3_t *hash_ctx;
const uint8_t *thash_ptr; const uint8_t *thash_ptr;
if ((hash_ctx = mem_alloc(sizeof(cx_sha3_t))) == NULL) if ((hash_ctx = MEM_ALLOC_AND_ALIGN_TO_TYPE(sizeof(*hash_ctx), *hash_ctx)) == NULL)
{ {
return false; return false;
} }
@@ -427,7 +428,8 @@ bool path_new_array_depth(uint8_t size)
} }
// TODO: Move elsewhere // TODO: Move elsewhere
cx_sha3_t *hash_ctx; cx_sha3_t *hash_ctx;
if ((hash_ctx = mem_alloc(sizeof(cx_sha3_t))) == NULL) // memory address not aligned, padd it
if ((hash_ctx = mem_alloc(sizeof(*hash_ctx))) == NULL)
{ {
return false; return false;
} }
@@ -533,7 +535,7 @@ bool path_advance(void)
} }
/** /**
* Allocates the the path indexes in memory and sets it with a depth of 0. * Allocates the path indexes in memory and sets it with a depth of 0.
* *
* @return whether the memory allocation were successful. * @return whether the memory allocation were successful.
*/ */
@@ -541,7 +543,7 @@ bool path_init(void)
{ {
if (path_struct == NULL) if (path_struct == NULL)
{ {
path_struct = mem_alloc(sizeof(*path_struct)); path_struct = MEM_ALLOC_AND_ALIGN_TO_TYPE(sizeof(*path_struct), *path_struct);
} }
return path_struct != NULL; return path_struct != NULL;
} }

View File

@@ -275,10 +275,14 @@ const uint8_t *type_hash(const void *const structs_array,
uint8_t deps_count = 0; uint8_t deps_count = 0;
void **deps; void **deps;
uint8_t *hash_ptr; uint8_t *hash_ptr;
void *mem_loc_bak = mem_alloc(0);
cx_keccak_init(&global_sha3, 256); // init hash cx_keccak_init(&global_sha3, 256); // init hash
// get list of structs (own + dependencies), properly ordered // get list of structs (own + dependencies), properly ordered
deps = mem_alloc(0); // get where the first elem will be if ((deps = MEM_ALLOC_AND_ALIGN_TO_TYPE(0, *deps)) == NULL)
{
return NULL;
}
if (get_struct_dependencies(structs_array, &deps_count, deps, struct_ptr) == false) if (get_struct_dependencies(structs_array, &deps_count, deps, struct_ptr) == false)
{ {
return NULL; return NULL;
@@ -294,7 +298,7 @@ const uint8_t *type_hash(const void *const structs_array,
encode_and_hash_type(*deps); encode_and_hash_type(*deps);
deps += 1; deps += 1;
} }
mem_dealloc(sizeof(void*) * deps_count); mem_dealloc(mem_alloc(0) - mem_loc_bak);
#ifdef DEBUG #ifdef DEBUG
PRINTF("\n"); PRINTF("\n");
#endif #endif