[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