[Forensics-changes] [yara] 314/368: Fix issue introduced in 23759af0b29bad2f407dd031de28598ea6952b96

Hilko Bengen bengen at moszumanska.debian.org
Sat Jul 1 10:30:52 UTC 2017


This is an automated email from the git hooks/post-receive script.

bengen pushed a commit to annotated tag v3.5.0
in repository yara.

commit 89a305f91de07ebfbeaf56a228140e10f27a8623
Author: plusvic <plusvic at gmail.com>
Date:   Tue Jun 14 20:29:05 2016 +0200

    Fix issue introduced in 23759af0b29bad2f407dd031de28598ea6952b96
    
    YR_MATCH was keeping a pointer to the original scanned data. With the introduction of iterator logic the original data is not guaranteed to be in memory by the time YR_MATCH is passed to library clients. Now a copy of the matching string is kept alongside the YR_MATCH structure.
---
 docs/capi.rst                 | 11 ++++++++--
 libyara/exec.c                |  5 +++--
 libyara/include/yara/limits.h |  1 +
 libyara/include/yara/types.h  | 43 ++++++++++++++++++++++---------------
 libyara/scan.c                | 50 +++++++++++++++++++++++++++++++------------
 tests/test-alignment.c        |  8 -------
 tests/util.c                  |  5 ++++-
 yara.c                        |  4 ++--
 8 files changed, 81 insertions(+), 46 deletions(-)

diff --git a/docs/capi.rst b/docs/capi.rst
index 240b5c9..bffa054 100644
--- a/docs/capi.rst
+++ b/docs/capi.rst
@@ -240,13 +240,20 @@ Data structures
 
     Offset of the match relative to *base*.
 
-  .. c:member:: int32_t length
+  .. c:member:: int32_t match_length
 
     Length of the matching string
 
   .. c:member:: uint8_t* data
 
-    Pointer to the matching string.
+    Pointer to a buffer containing a portion of the matching string.
+
+  .. c:member:: int32_t data_length
+
+    Length of ``data`` buffer. ``data_length`` is the minimum of
+    ``match_length`` and ``MAX_MATCH_DATA``.
+
+  .. versionchanged:: 3.5.0
 
 .. c:type:: YR_META
 
diff --git a/libyara/exec.c b/libyara/exec.c
index 5cf371c..a06688f 100644
--- a/libyara/exec.c
+++ b/libyara/exec.c
@@ -103,7 +103,8 @@ typedef union _STACK_ITEM {
             offset <= block->base + block->size - sizeof(type)) \
         { \
           uint8_t* data = iterator->fetch_data(iterator); \
-          if(data == NULL) return UNDEFINED; \
+          if (data == NULL) \
+            return UNDEFINED; \
           type result = *(type *)(data + offset - block->base); \
           result = endianess##_##type(result); \
           return result; \
@@ -696,7 +697,7 @@ int yr_execute_code(
         while (match != NULL && r3.i == UNDEFINED)
         {
           if (r1.i == i)
-            r3.i = match->length;
+            r3.i = match->match_length;
 
           i++;
           match = match->next;
diff --git a/libyara/include/yara/limits.h b/libyara/include/yara/limits.h
index 7dea042..12a1119 100644
--- a/libyara/include/yara/limits.h
+++ b/libyara/include/yara/limits.h
@@ -43,6 +43,7 @@ limitations under the License.
 #define MAX_FAST_HEX_RE_STACK           300
 #define MAX_OVERLOADED_FUNCTIONS        10
 #define MAX_HEX_STRING_TOKENS           10000
+#define MAX_MATCH_DATA                  4096
 
 #define LOOP_LOCAL_VARS                 4
 #define STRING_CHAINING_THRESHOLD       200
diff --git a/libyara/include/yara/types.h b/libyara/include/yara/types.h
index 5281cf2..73b5c88 100644
--- a/libyara/include/yara/types.h
+++ b/libyara/include/yara/types.h
@@ -182,29 +182,15 @@ typedef struct _YR_META
 } YR_META;
 
 
-typedef struct _YR_MATCH
-{
-  int64_t base;
-  int64_t offset;
-  int32_t length;
-
-  union {
-    uint8_t* data;           // Confirmed matches use "data",
-    int32_t chain_length;    // unconfirmed ones use "chain_length"
-  } YR_ALIGN(8);
-
-  YR_ALIGN(8) struct _YR_MATCH* prev;
-  YR_ALIGN(8) struct _YR_MATCH* next;
-
-} YR_MATCH;
+struct _YR_MATCH;
 
 
 typedef struct _YR_MATCHES
 {
   int32_t count;
 
-  DECLARE_REFERENCE(YR_MATCH*, head);
-  DECLARE_REFERENCE(YR_MATCH*, tail);
+  DECLARE_REFERENCE(struct _YR_MATCH*, head);
+  DECLARE_REFERENCE(struct _YR_MATCH*, tail);
 
 } YR_MATCHES;
 
@@ -309,6 +295,29 @@ typedef struct _YARA_RULES_FILE_HEADER
 // Structs defined below are never stored in the compiled rules file
 //
 
+typedef struct _YR_MATCH
+{
+  int64_t base;              // Base address for the match
+  int64_t offset;            // Offset relative to base for the match
+  int32_t match_length;      // Match length
+  int32_t data_length;
+
+  // Pointer to a buffer containing a portion of the matched data. The size of
+  // the buffer is data_length. data_length is always <= length and is limited
+  // to MAX_MATCH_DATA bytes.
+
+  uint8_t* data;
+
+  // If the match belongs to a chained string chain_length contains the
+  // length of the chain. This field is used only in unconfirmed matches.
+
+  int32_t chain_length;
+
+  struct _YR_MATCH* prev;
+  struct _YR_MATCH* next;
+
+} YR_MATCH;
+
 
 struct _YR_AC_STATE;
 
diff --git a/libyara/scan.c b/libyara/scan.c
index 4c40239..97490f5 100644
--- a/libyara/scan.c
+++ b/libyara/scan.c
@@ -385,7 +385,7 @@ void _yr_scan_update_match_chain_length(
 
   while (match != NULL)
   {
-    int64_t ending_offset = match->offset + match->length;
+    int64_t ending_offset = match->offset + match->match_length;
 
     if (ending_offset + string->chain_gap_max >= match_to_update->offset &&
         ending_offset + string->chain_gap_min <= match_to_update->offset)
@@ -414,7 +414,11 @@ int _yr_scan_add_match_to_list(
     if (match->offset == insertion_point->offset)
     {
       if (replace_if_exists)
-        insertion_point->length = match->length;
+      {
+        insertion_point->match_length = match->match_length;
+        insertion_point->data_length = match->data_length;
+        insertion_point->data = match->data;
+      }
 
       return ERROR_SUCCESS;
     }
@@ -507,7 +511,7 @@ int _yr_scan_verify_chained_string_match(
     while (match != NULL)
     {
       next_match = match->next;
-      ending_offset = match->offset + match->length;
+      ending_offset = match->offset + match->match_length;
 
       if (ending_offset + matching_string->chain_gap_max < lower_offset)
       {
@@ -536,7 +540,7 @@ int _yr_scan_verify_chained_string_match(
 
       while (match != NULL)
       {
-        ending_offset = match->offset + match->length;
+        ending_offset = match->offset + match->match_length;
 
         if (ending_offset + matching_string->chain_gap_max >= match_offset &&
             ending_offset + matching_string->chain_gap_min <= match_offset)
@@ -570,12 +574,16 @@ int _yr_scan_verify_chained_string_match(
           _yr_scan_remove_match_from_list(
               match, &string->unconfirmed_matches[tidx]);
 
-          match->length = (int32_t) \
+          match->match_length = (int32_t) \
               (match_offset - match->offset + match_length);
 
-          match->data = match_data - match_offset + match->offset;
-          match->prev = NULL;
-          match->next = NULL;
+          match->data_length = yr_min(match->match_length, MAX_MATCH_DATA);
+
+          FAIL_ON_ERROR(yr_arena_write_data(
+              context->matches_arena,
+              match_data - match_offset + match->offset,
+              match->data_length,
+              (void**) &match->data));
 
           FAIL_ON_ERROR(_yr_scan_add_match_to_list(
               match, &string->matches[tidx], FALSE));
@@ -604,10 +612,17 @@ int _yr_scan_verify_chained_string_match(
           sizeof(YR_MATCH),
           (void**) &new_match));
 
+      new_match->data_length = yr_min(match_length, MAX_MATCH_DATA);
+
+      FAIL_ON_ERROR(yr_arena_write_data(
+          context->matches_arena,
+          match_data,
+          new_match->data_length,
+          (void**) &new_match->data));
+
       new_match->base = match_base;
       new_match->offset = match_offset;
-      new_match->length = match_length;
-      new_match->data = match_data;
+      new_match->match_length = match_length;
       new_match->chain_length = 0;
       new_match->prev = NULL;
       new_match->next = NULL;
@@ -692,17 +707,24 @@ int _yr_scan_match_callback(
           NULL));
     }
 
-    result = yr_arena_allocate_memory(
+    FAIL_ON_ERROR(yr_arena_allocate_memory(
         callback_args->context->matches_arena,
         sizeof(YR_MATCH),
-        (void**) &new_match);
+        (void**) &new_match));
+
+    new_match->data_length = yr_min(match_length, MAX_MATCH_DATA);
+
+    FAIL_ON_ERROR(yr_arena_write_data(
+        callback_args->context->matches_arena,
+        match_data,
+        new_match->data_length,
+        (void**) &new_match->data));
 
     if (result == ERROR_SUCCESS)
     {
       new_match->base = callback_args->data_base;
       new_match->offset = match_offset;
-      new_match->length = match_length;
-      new_match->data = match_data;
+      new_match->match_length = match_length;
       new_match->prev = NULL;
       new_match->next = NULL;
 
diff --git a/tests/test-alignment.c b/tests/test-alignment.c
index dc33c3e..6885616 100644
--- a/tests/test-alignment.c
+++ b/tests/test-alignment.c
@@ -60,14 +60,6 @@ int main (int argc, char **argv)
   CHECK_OFFSET(YR_META, 16, identifier);
   CHECK_OFFSET(YR_META, 24, string);
 
-  CHECK_SIZE(YR_MATCH, 48);
-  CHECK_OFFSET(YR_MATCH, 8,  offset);
-  CHECK_OFFSET(YR_MATCH, 16, length);
-  CHECK_OFFSET(YR_MATCH, 24, data);
-  CHECK_OFFSET(YR_MATCH, 24, chain_length);
-  CHECK_OFFSET(YR_MATCH, 32, prev);
-  CHECK_OFFSET(YR_MATCH, 40, next);
-
   CHECK_SIZE(YR_MATCHES, 24);
   CHECK_OFFSET(YR_MATCHES, 8,  head);
   CHECK_OFFSET(YR_MATCHES, 16, tail);
diff --git a/tests/util.c b/tests/util.c
index a211f54..07b856c 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -156,7 +156,10 @@ static int capture_matches(
 
       yr_string_matches_foreach(string, match)
       {
-        if (strncmp(f->expected, (char*)(match->data), match->length) == 0)
+        int r = strncmp(
+            f->expected, (char*) (match->data), match->data_length);
+            
+        if (r == 0)
           f->found++;
       }
     }
diff --git a/yara.c b/yara.c
index 03b706d..36fbbe5 100644
--- a/yara.c
+++ b/yara.c
@@ -643,9 +643,9 @@ int handle_message(
               string->identifier);
 
           if (STRING_IS_HEX(string))
-            print_hex_string(match->data, match->length);
+            print_hex_string(match->data, match->data_length);
           else
-            print_string(match->data, match->length);
+            print_string(match->data, match->data_length);
         }
       }
     }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/yara.git



More information about the forensics-changes mailing list