Skip to content

Commit e1654ae

Browse files
hilluplusvic
authored andcommitted
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.
1 parent 63a2b59 commit e1654ae

File tree

3 files changed

+27
-13
lines changed

3 files changed

+27
-13
lines changed

libyara/arena.c

+6
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,12 @@ void* yr_arena_ref_to_ptr(
435435
if (YR_ARENA_IS_NULL_REF(*ref))
436436
return NULL;
437437

438+
#if defined(__arm__)
439+
YR_ARENA_REF tmp_ref;
440+
memcpy(&tmp_ref, ref, sizeof(YR_ARENA_REF));
441+
ref = &tmp_ref;
442+
#endif
443+
438444
return yr_arena_get_ptr(arena, ref->buffer_id, ref->offset);
439445
}
440446

libyara/exec.c

+12-13
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ int yr_execute_code(
540540
break;
541541

542542
case OP_PUSH:
543-
r1.i = *(uint64_t*)(ip);
543+
memcpy(&r1.i, ip, sizeof(uint64_t));
544544
ip += sizeof(uint64_t);
545545
push(r1);
546546
break;
@@ -550,7 +550,7 @@ int yr_execute_code(
550550
break;
551551

552552
case OP_CLEAR_M:
553-
r1.i = *(uint64_t*)(ip);
553+
memcpy(&r1.i, ip, sizeof(uint64_t));
554554
ip += sizeof(uint64_t);
555555
#if YR_PARANOID_EXEC
556556
ensure_within_mem(r1.i);
@@ -559,7 +559,7 @@ int yr_execute_code(
559559
break;
560560

561561
case OP_ADD_M:
562-
r1.i = *(uint64_t*)(ip);
562+
memcpy(&r1.i, ip, sizeof(uint64_t));
563563
ip += sizeof(uint64_t);
564564
#if YR_PARANOID_EXEC
565565
ensure_within_mem(r1.i);
@@ -570,7 +570,7 @@ int yr_execute_code(
570570
break;
571571

572572
case OP_INCR_M:
573-
r1.i = *(uint64_t*)(ip);
573+
memcpy(&r1.i, ip, sizeof(uint64_t));
574574
ip += sizeof(uint64_t);
575575
#if YR_PARANOID_EXEC
576576
ensure_within_mem(r1.i);
@@ -579,7 +579,7 @@ int yr_execute_code(
579579
break;
580580

581581
case OP_PUSH_M:
582-
r1.i = *(uint64_t*)(ip);
582+
memcpy(&r1.i, ip, sizeof(uint64_t));
583583
ip += sizeof(uint64_t);
584584
#if YR_PARANOID_EXEC
585585
ensure_within_mem(r1.i);
@@ -589,7 +589,7 @@ int yr_execute_code(
589589
break;
590590

591591
case OP_POP_M:
592-
r1.i = *(uint64_t*)(ip);
592+
memcpy(&r1.i, ip, sizeof(uint64_t));
593593
ip += sizeof(uint64_t);
594594
#if YR_PARANOID_EXEC
595595
ensure_within_mem(r1.i);
@@ -599,7 +599,7 @@ int yr_execute_code(
599599
break;
600600

601601
case OP_SET_M:
602-
r1.i = *(uint64_t*)(ip);
602+
memcpy(&r1.i, ip, sizeof(uint64_t));
603603
ip += sizeof(uint64_t);
604604
#if YR_PARANOID_EXEC
605605
ensure_within_mem(r1.i);
@@ -611,7 +611,7 @@ int yr_execute_code(
611611
break;
612612

613613
case OP_SWAPUNDEF:
614-
r1.i = *(uint64_t*)(ip);
614+
memcpy(&r1.i, ip, sizeof(uint64_t));
615615
ip += sizeof(uint64_t);
616616
#if YR_PARANOID_EXEC
617617
ensure_within_mem(r1.i);
@@ -802,7 +802,7 @@ int yr_execute_code(
802802
break;
803803

804804
case OP_PUSH_RULE:
805-
r1.i = *(uint64_t*)(ip);
805+
memcpy(&r1.i, ip, sizeof(uint64_t));
806806
ip += sizeof(uint64_t);
807807

808808
rule = &context->rules->rules_list_head[r1.i];
@@ -841,7 +841,7 @@ int yr_execute_code(
841841
case OP_MATCH_RULE:
842842
pop(r1);
843843

844-
r2.i = *(uint64_t*)(ip);
844+
memcpy(&r2.i, ip, sizeof(uint64_t));
845845
ip += sizeof(uint64_t);
846846

847847
rule = &context->rules->rules_list_head[r2.i];
@@ -1316,7 +1316,7 @@ int yr_execute_code(
13161316
break;
13171317

13181318
case OP_IMPORT:
1319-
r1.i = *(uint64_t*)(ip);
1319+
memcpy(&r1.i, ip, sizeof(uint64_t));
13201320
ip += sizeof(uint64_t);
13211321

13221322
result = yr_modules_load((char*) r1.p, context);
@@ -1356,8 +1356,7 @@ int yr_execute_code(
13561356
break;
13571357

13581358
case OP_INT_TO_DBL:
1359-
1360-
r1.i = *(uint64_t*)(ip);
1359+
memcpy(&r1.i, ip, sizeof(uint64_t));
13611360
ip += sizeof(uint64_t);
13621361

13631362
#if YR_PARANOID_EXEC

libyara/notebook.c

+9
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,15 @@ void* yr_notebook_alloc(
146146

147147
void *ptr = notebook->page_list_head->data + notebook->page_list_head->used;
148148

149+
#if defined(__arm__)
150+
uintptr_t misalignment = (uintptr_t)ptr & 3;
151+
if (misalignment)
152+
{
153+
size += 4-misalignment;
154+
ptr += 4-misalignment;
155+
}
156+
#endif
157+
149158
notebook->page_list_head->used += size;
150159

151160
return ptr;

0 commit comments

Comments
 (0)