Package: yara
Followup-For: Bug #869777
User: ubuntu-de...@lists.ubuntu.com
Usertags: origin-ubuntu bionic ubuntu-patch

Hi Hilko,

I've applied the following patch to yara in Ubuntu which fixes the
non-portable alignment assumptions.  This should be reasonably performant
with modern gcc on supported architectures, and on some architectures will
likely improve performance by eliminating unaligned accesses that are
supported but costly to fix up.  (This includes ARM in some configurations,
since it's possible for unaligned access to not raise SIGBUS but still be an
expensive operation.)

Please consider applying this patch in Debian.

Thanks,
-- 
Steve Langasek                   Give me a lever long enough and a Free OS
Debian Developer                   to set it on, and I can move the world.
Ubuntu Developer                                    http://www.debian.org/
slanga...@ubuntu.com                                     vor...@debian.org
diff -Nru yara-3.7.1/debian/patches/no-unaligned-access.patch 
yara-3.7.1/debian/patches/no-unaligned-access.patch
--- yara-3.7.1/debian/patches/no-unaligned-access.patch 1969-12-31 
16:00:00.000000000 -0800
+++ yara-3.7.1/debian/patches/no-unaligned-access.patch 2018-02-04 
14:08:33.000000000 -0800
@@ -0,0 +1,118 @@
+Description: use alignment-safe handling
+ Casting a char* to a uint64_t* is not universally safe due to alignment
+ constraints on reads on some platforms.  Just use memcpy() instead, which
+ the compiler should optimize adequately for us.
+ .
+ Also, force alignment of our arena-allocated structures that contain 64-bit
+ elements.
+Author: Steve Langasek <steve.langa...@ubuntu.com>
+
+Index: yara-3.7.1/libyara/exec.c
+===================================================================
+--- yara-3.7.1.orig/libyara/exec.c
++++ yara-3.7.1/libyara/exec.c
+@@ -227,7 +227,7 @@
+         break;
+ 
+       case OP_PUSH:
+-        r1.i = *(uint64_t*)(ip);
++        memcpy(&r1.i, ip, sizeof(uint64_t));
+         ip += sizeof(uint64_t);
+         push(r1);
+         break;
+@@ -237,13 +237,13 @@
+         break;
+ 
+       case OP_CLEAR_M:
+-        r1.i = *(uint64_t*)(ip);
++        memcpy(&r1.i, ip, sizeof(uint64_t));
+         ip += sizeof(uint64_t);
+         mem[r1.i] = 0;
+         break;
+ 
+       case OP_ADD_M:
+-        r1.i = *(uint64_t*)(ip);
++        memcpy(&r1.i, ip, sizeof(uint64_t));
+         ip += sizeof(uint64_t);
+         pop(r2);
+         if (!is_undef(r2))
+@@ -251,27 +251,27 @@
+         break;
+ 
+       case OP_INCR_M:
+-        r1.i = *(uint64_t*)(ip);
++        memcpy(&r1.i, ip, sizeof(uint64_t));
+         ip += sizeof(uint64_t);
+         mem[r1.i]++;
+         break;
+ 
+       case OP_PUSH_M:
+-        r1.i = *(uint64_t*)(ip);
++        memcpy(&r1.i, ip, sizeof(uint64_t));
+         ip += sizeof(uint64_t);
+         r1.i = mem[r1.i];
+         push(r1);
+         break;
+ 
+       case OP_POP_M:
+-        r1.i = *(uint64_t*)(ip);
++        memcpy(&r1.i, ip, sizeof(uint64_t));
+         ip += sizeof(uint64_t);
+         pop(r2);
+         mem[r1.i] = r2.i;
+         break;
+ 
+       case OP_SWAPUNDEF:
+-        r1.i = *(uint64_t*)(ip);
++        memcpy(&r1.i, ip, sizeof(uint64_t));
+         ip += sizeof(uint64_t);
+         pop(r2);
+ 
+@@ -859,7 +859,7 @@
+         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);
+@@ -902,7 +902,7 @@
+         break;
+ 
+       case OP_INT_TO_DBL:
+-        r1.i = *(uint64_t*)(ip);
++        memcpy(&r1.i, ip, sizeof(uint64_t));
+         ip += sizeof(uint64_t);
+         r2 = stack[sp - r1.i];
+         if (is_undef(r2))
+Index: yara-3.7.1/libyara/scan.c
+===================================================================
+--- yara-3.7.1.orig/libyara/scan.c
++++ yara-3.7.1/libyara/scan.c
+@@ -397,8 +397,11 @@
+ 
+       FAIL_ON_ERROR(yr_arena_allocate_memory(
+           context->matches_arena,
+-          sizeof(YR_MATCH),
++          sizeof(YR_MATCH) + sizeof(uint64_t) - 1,
+           (void**) &new_match));
++      /* force alignment */
++      new_match = (YR_MATCH *)(((size_t)new_match + sizeof(uint64_t) - 1)
++                      & ~(sizeof(uint64_t) - 1));
+ 
+       new_match->data_length = yr_min(match_length, MAX_MATCH_DATA);
+ 
+@@ -500,8 +503,11 @@
+ 
+     FAIL_ON_ERROR(yr_arena_allocate_memory(
+         callback_args->context->matches_arena,
+-        sizeof(YR_MATCH),
++        sizeof(YR_MATCH) + sizeof(uint64_t) - 1,
+         (void**) &new_match));
++    /* force alignment */
++    new_match = (YR_MATCH *)(((size_t)new_match + sizeof(uint64_t) - 1)
++                    & ~(sizeof(uint64_t) - 1));
+ 
+     new_match->data_length = yr_min(match_length, MAX_MATCH_DATA);
+ 
diff -Nru yara-3.7.1/debian/patches/series yara-3.7.1/debian/patches/series
--- yara-3.7.1/debian/patches/series    2018-01-16 04:45:26.000000000 -0800
+++ yara-3.7.1/debian/patches/series    2018-02-04 14:04:53.000000000 -0800
@@ -1 +1,2 @@
 0001-Use-Linux-style-procfs-on-kFreeBSD-because-struct-pt.patch
+no-unaligned-access.patch

Reply via email to