From e1654ae49c14954f18cc442885b0556ebed5aced Mon Sep 17 00:00:00 2001 From: Hilko Bengen Date: Fri, 1 May 2020 01:03:14 +0200 Subject: [PATCH] Fix unaligned data accesses on ARM Some unaligned data access patterns are not entirely OK on Linux/ARM. Depending on kernel configuration, it may cause bus errors or "only" lead to massive slowdowns as the kernel works around faulting instructions and perhaps even emits log messages. (This option does not seem to exist for 32 bit code running on an ARM64 kernel, though.) Most of this patch which was originally developed by Steve Langasek has been part of the Debian package for a while. --- libyara/arena.c | 6 ++++++ libyara/exec.c | 25 ++++++++++++------------- libyara/notebook.c | 9 +++++++++ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/libyara/arena.c b/libyara/arena.c index 319cff46b8..f2c74b7e9b 100644 --- a/libyara/arena.c +++ b/libyara/arena.c @@ -435,6 +435,12 @@ void* yr_arena_ref_to_ptr( if (YR_ARENA_IS_NULL_REF(*ref)) return NULL; +#if defined(__arm__) + YR_ARENA_REF tmp_ref; + memcpy(&tmp_ref, ref, sizeof(YR_ARENA_REF)); + ref = &tmp_ref; +#endif + return yr_arena_get_ptr(arena, ref->buffer_id, ref->offset); } diff --git a/libyara/exec.c b/libyara/exec.c index 431461d8fa..513aa920e6 100644 --- a/libyara/exec.c +++ b/libyara/exec.c @@ -540,7 +540,7 @@ int yr_execute_code( break; case OP_PUSH: - r1.i = *(uint64_t*)(ip); + memcpy(&r1.i, ip, sizeof(uint64_t)); ip += sizeof(uint64_t); push(r1); break; @@ -550,7 +550,7 @@ int yr_execute_code( break; case OP_CLEAR_M: - r1.i = *(uint64_t*)(ip); + memcpy(&r1.i, ip, sizeof(uint64_t)); ip += sizeof(uint64_t); #if YR_PARANOID_EXEC ensure_within_mem(r1.i); @@ -559,7 +559,7 @@ int yr_execute_code( break; case OP_ADD_M: - r1.i = *(uint64_t*)(ip); + memcpy(&r1.i, ip, sizeof(uint64_t)); ip += sizeof(uint64_t); #if YR_PARANOID_EXEC ensure_within_mem(r1.i); @@ -570,7 +570,7 @@ int yr_execute_code( break; case OP_INCR_M: - r1.i = *(uint64_t*)(ip); + memcpy(&r1.i, ip, sizeof(uint64_t)); ip += sizeof(uint64_t); #if YR_PARANOID_EXEC ensure_within_mem(r1.i); @@ -579,7 +579,7 @@ int yr_execute_code( break; case OP_PUSH_M: - r1.i = *(uint64_t*)(ip); + memcpy(&r1.i, ip, sizeof(uint64_t)); ip += sizeof(uint64_t); #if YR_PARANOID_EXEC ensure_within_mem(r1.i); @@ -589,7 +589,7 @@ int yr_execute_code( break; case OP_POP_M: - r1.i = *(uint64_t*)(ip); + memcpy(&r1.i, ip, sizeof(uint64_t)); ip += sizeof(uint64_t); #if YR_PARANOID_EXEC ensure_within_mem(r1.i); @@ -599,7 +599,7 @@ int yr_execute_code( break; case OP_SET_M: - r1.i = *(uint64_t*)(ip); + memcpy(&r1.i, ip, sizeof(uint64_t)); ip += sizeof(uint64_t); #if YR_PARANOID_EXEC ensure_within_mem(r1.i); @@ -611,7 +611,7 @@ int yr_execute_code( break; case OP_SWAPUNDEF: - r1.i = *(uint64_t*)(ip); + memcpy(&r1.i, ip, sizeof(uint64_t)); ip += sizeof(uint64_t); #if YR_PARANOID_EXEC ensure_within_mem(r1.i); @@ -802,7 +802,7 @@ int yr_execute_code( break; case OP_PUSH_RULE: - r1.i = *(uint64_t*)(ip); + memcpy(&r1.i, ip, sizeof(uint64_t)); ip += sizeof(uint64_t); rule = &context->rules->rules_list_head[r1.i]; @@ -841,7 +841,7 @@ int yr_execute_code( case OP_MATCH_RULE: pop(r1); - r2.i = *(uint64_t*)(ip); + memcpy(&r2.i, ip, sizeof(uint64_t)); ip += sizeof(uint64_t); rule = &context->rules->rules_list_head[r2.i]; @@ -1316,7 +1316,7 @@ int yr_execute_code( break; case OP_IMPORT: - r1.i = *(uint64_t*)(ip); + memcpy(&r1.i, ip, sizeof(uint64_t)); ip += sizeof(uint64_t); result = yr_modules_load((char*) r1.p, context); @@ -1356,8 +1356,7 @@ int yr_execute_code( break; case OP_INT_TO_DBL: - - r1.i = *(uint64_t*)(ip); + memcpy(&r1.i, ip, sizeof(uint64_t)); ip += sizeof(uint64_t); #if YR_PARANOID_EXEC diff --git a/libyara/notebook.c b/libyara/notebook.c index bcf52a5f68..375ed5dfc3 100644 --- a/libyara/notebook.c +++ b/libyara/notebook.c @@ -146,6 +146,15 @@ void* yr_notebook_alloc( void *ptr = notebook->page_list_head->data + notebook->page_list_head->used; +#if defined(__arm__) + uintptr_t misalignment = (uintptr_t)ptr & 3; + if (misalignment) + { + size += 4-misalignment; + ptr += 4-misalignment; + } +#endif + notebook->page_list_head->used += size; return ptr;