[Forensics-changes] [yara] 179/368: Put a limit to the number of fibers while executing a regex
Hilko Bengen
bengen at moszumanska.debian.org
Sat Jul 1 10:30:27 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 510fc3db02183613fab6b1bab60f4e94e52ea866
Author: plusvic <plusvic at gmail.com>
Date: Tue Feb 23 12:07:15 2016 +0100
Put a limit to the number of fibers while executing a regex
---
libyara/include/yara/error.h | 1 +
libyara/re.c | 165 ++++++++++++++++++++++++-------------------
libyara/scan.c | 4 ++
3 files changed, 97 insertions(+), 73 deletions(-)
diff --git a/libyara/include/yara/error.h b/libyara/include/yara/error.h
index fa9f312..9ce31e7 100644
--- a/libyara/include/yara/error.h
+++ b/libyara/include/yara/error.h
@@ -71,6 +71,7 @@ limitations under the License.
#define ERROR_EMPTY_STRING 43
#define ERROR_DIVISION_BY_ZERO 44
#define ERROR_REGULAR_EXPRESSION_TOO_LARGE 45
+#define ERROR_TOO_MANY_RE_FIBERS 46
#define FAIL_ON_ERROR(x) { \
diff --git a/libyara/re.c b/libyara/re.c
index 932d1fd..e25b78b 100644
--- a/libyara/re.c
+++ b/libyara/re.c
@@ -44,11 +44,10 @@ order to avoid confusion with operating system threads.
#include <yara/re_lexer.h>
#include <yara/hex_lexer.h>
-
// Maximum allowed split ID, also limiting the number of split instructions
// allowed in a regular expression. This number can't be increased
// over 255 without changing RE_SPLIT_ID_TYPE.
-#define RE_MAX_SPLIT_ID 255
+#define RE_MAX_SPLIT_ID 128
// Maxium stack size for regexp evaluation
#define RE_MAX_STACK 1024
@@ -59,6 +58,9 @@ order to avoid confusion with operating system threads.
// Maximum input size scanned by yr_re_exec
#define RE_SCAN_LIMIT 4096
+// Maxium number of fibers
+#define RE_MAX_FIBERS 64
+
#define EMIT_BACKWARDS 0x01
#define EMIT_DONT_SET_FORWARDS_CODE 0x02
@@ -74,6 +76,7 @@ typedef struct _RE_EMIT_CONTEXT {
} RE_EMIT_CONTEXT;
+
typedef struct _RE_FIBER
{
RE_CODE ip;
@@ -95,9 +98,17 @@ typedef struct _RE_FIBER_LIST
} RE_FIBER_LIST;
+typedef struct _RE_FIBER_POOL
+{
+ int fiber_count;
+ RE_FIBER_LIST fibers;
+
+} RE_FIBER_POOL;
+
+
typedef struct _RE_THREAD_STORAGE
{
- RE_FIBER_LIST fiber_pool;
+ RE_FIBER_POOL fiber_pool;
} RE_THREAD_STORAGE;
@@ -169,7 +180,7 @@ int yr_re_finalize_thread(void)
if (storage != NULL)
{
- fiber = storage->fiber_pool.head;
+ fiber = storage->fiber_pool.fibers.head;
while (fiber != NULL)
{
@@ -1258,8 +1269,9 @@ int _yr_re_alloc_storage(
if (*storage == NULL)
return ERROR_INSUFICIENT_MEMORY;
- (*storage)->fiber_pool.head = NULL;
- (*storage)->fiber_pool.tail = NULL;
+ (*storage)->fiber_pool.fiber_count = 0;
+ (*storage)->fiber_pool.fibers.head = NULL;
+ (*storage)->fiber_pool.fibers.tail = NULL;
#if defined(_WIN32) || defined(__CYGWIN__)
TlsSetValue(thread_storage_key, *storage);
@@ -1272,32 +1284,41 @@ int _yr_re_alloc_storage(
}
-RE_FIBER* _yr_re_fiber_create(
- RE_FIBER_LIST* fiber_pool)
+int _yr_re_fiber_create(
+ RE_FIBER_POOL* fiber_pool,
+ RE_FIBER** new_fiber)
{
RE_FIBER* fiber;
- if (fiber_pool->head != NULL)
+ if (fiber_pool->fiber_count == RE_MAX_FIBERS)
+ return ERROR_TOO_MANY_RE_FIBERS;
+
+ if (fiber_pool->fibers.head != NULL)
{
- fiber = fiber_pool->head;
- fiber_pool->head = fiber->next;
- if (fiber_pool->tail == fiber)
- fiber_pool->tail = NULL;
+ fiber = fiber_pool->fibers.head;
+ fiber_pool->fibers.head = fiber->next;
+
+ if (fiber_pool->fibers.tail == fiber)
+ fiber_pool->fibers.tail = NULL;
}
else
{
fiber = (RE_FIBER*) yr_malloc(sizeof(RE_FIBER));
- }
- if (fiber != NULL)
- {
- fiber->ip = NULL;
- fiber->sp = -1;
- fiber->next = NULL;
- fiber->prev = NULL;
+ if (fiber == NULL)
+ return ERROR_INSUFICIENT_MEMORY;
+
+ fiber_pool->fiber_count++;
}
- return fiber;
+ fiber->ip = NULL;
+ fiber->sp = -1;
+ fiber->next = NULL;
+ fiber->prev = NULL;
+
+ *new_fiber = fiber;
+
+ return ERROR_SUCCESS;
}
@@ -1392,40 +1413,37 @@ int _yr_re_fiber_exists(
//
//
-RE_FIBER* _yr_re_fiber_split(
+int _yr_re_fiber_split(
RE_FIBER* fiber,
RE_FIBER_LIST* fiber_list,
- RE_FIBER_LIST* fiber_pool)
+ RE_FIBER_POOL* fiber_pool,
+ RE_FIBER** new_fiber)
{
- RE_FIBER* new_fiber;
int32_t i;
- new_fiber = _yr_re_fiber_create(fiber_pool);
-
- if (new_fiber == NULL)
- return NULL;
+ FAIL_ON_ERROR(_yr_re_fiber_create(fiber_pool, new_fiber));
- new_fiber->sp = fiber->sp;
- new_fiber->ip = fiber->ip;
+ (*new_fiber)->sp = fiber->sp;
+ (*new_fiber)->ip = fiber->ip;
for (i = 0; i <= fiber->sp; i++)
- new_fiber->stack[i] = fiber->stack[i];
+ (*new_fiber)->stack[i] = fiber->stack[i];
- new_fiber->next = fiber->next;
- new_fiber->prev = fiber;
+ (*new_fiber)->next = fiber->next;
+ (*new_fiber)->prev = fiber;
if (fiber->next != NULL)
- fiber->next->prev = new_fiber;
+ fiber->next->prev = *new_fiber;
- fiber->next = new_fiber;
+ fiber->next = *new_fiber;
if (fiber_list->tail == fiber)
- fiber_list->tail = new_fiber;
+ fiber_list->tail = *new_fiber;
assert(fiber_list->tail->next == NULL);
assert(fiber_list->head->prev == NULL);
- return new_fiber;
+ return ERROR_SUCCESS;
}
@@ -1438,7 +1456,7 @@ RE_FIBER* _yr_re_fiber_split(
RE_FIBER* _yr_re_fiber_kill(
RE_FIBER_LIST* fiber_list,
- RE_FIBER_LIST* fiber_pool,
+ RE_FIBER_POOL* fiber_pool,
RE_FIBER* fiber)
{
RE_FIBER* next_fiber = fiber->next;
@@ -1449,8 +1467,8 @@ RE_FIBER* _yr_re_fiber_kill(
if (next_fiber != NULL)
next_fiber->prev = fiber->prev;
- if (fiber_pool->tail != NULL)
- fiber_pool->tail->next = fiber;
+ if (fiber_pool->fibers.tail != NULL)
+ fiber_pool->fibers.tail->next = fiber;
if (fiber_list->tail == fiber)
fiber_list->tail = fiber->prev;
@@ -1459,11 +1477,11 @@ RE_FIBER* _yr_re_fiber_kill(
fiber_list->head = next_fiber;
fiber->next = NULL;
- fiber->prev = fiber_pool->tail;
- fiber_pool->tail = fiber;
+ fiber->prev = fiber_pool->fibers.tail;
+ fiber_pool->fibers.tail = fiber;
- if (fiber_pool->head == NULL)
- fiber_pool->head = fiber;
+ if (fiber_pool->fibers.head == NULL)
+ fiber_pool->fibers.head = fiber;
return next_fiber;
}
@@ -1477,7 +1495,7 @@ RE_FIBER* _yr_re_fiber_kill(
void _yr_re_fiber_kill_tail(
RE_FIBER_LIST* fiber_list,
- RE_FIBER_LIST* fiber_pool,
+ RE_FIBER_POOL* fiber_pool,
RE_FIBER* fiber)
{
RE_FIBER* prev_fiber = fiber->prev;
@@ -1485,19 +1503,19 @@ void _yr_re_fiber_kill_tail(
if (prev_fiber != NULL)
prev_fiber->next = NULL;
- fiber->prev = fiber_pool->tail;
+ fiber->prev = fiber_pool->fibers.tail;
- if (fiber_pool->tail != NULL)
- fiber_pool->tail->next = fiber;
+ if (fiber_pool->fibers.tail != NULL)
+ fiber_pool->fibers.tail->next = fiber;
- fiber_pool->tail = fiber_list->tail;
+ fiber_pool->fibers.tail = fiber_list->tail;
fiber_list->tail = prev_fiber;
if (fiber_list->head == fiber)
fiber_list->head = NULL;
- if (fiber_pool->head == NULL)
- fiber_pool->head = fiber;
+ if (fiber_pool->fibers.head == NULL)
+ fiber_pool->fibers.head = fiber;
}
@@ -1509,7 +1527,7 @@ void _yr_re_fiber_kill_tail(
void _yr_re_fiber_kill_all(
RE_FIBER_LIST* fiber_list,
- RE_FIBER_LIST* fiber_pool)
+ RE_FIBER_POOL* fiber_pool)
{
if (fiber_list->head != NULL)
_yr_re_fiber_kill_tail(fiber_list, fiber_pool, fiber_list->head);
@@ -1527,7 +1545,7 @@ void _yr_re_fiber_kill_all(
int _yr_re_fiber_sync(
RE_FIBER_LIST* fiber_list,
- RE_FIBER_LIST* fiber_pool,
+ RE_FIBER_POOL* fiber_pool,
RE_FIBER* fiber_to_sync)
{
// A array for keeping track of which split instructions has been already
@@ -1577,10 +1595,8 @@ int _yr_re_fiber_sync(
}
else
{
- new_fiber = _yr_re_fiber_split(fiber, fiber_list, fiber_pool);
-
- if (new_fiber == NULL)
- return ERROR_INSUFICIENT_MEMORY;
+ FAIL_ON_ERROR(_yr_re_fiber_split(
+ fiber, fiber_list, fiber_pool, &new_fiber));
if (*fiber->ip == RE_OPCODE_SPLIT_A)
{
@@ -1665,7 +1681,8 @@ int _yr_re_fiber_sync(
// -1 No match
// -2 Not enough memory
// -3 Too many matches
-// -4 Unknown fatal error
+// -4 Too many fibers
+// -5 Unknown fatal error
int yr_re_exec(
RE_CODE re_code,
@@ -1706,6 +1723,13 @@ int yr_re_exec(
break; \
}
+ #define fail_if_error(e) switch (e) { \
+ case ERROR_INSUFICIENT_MEMORY: \
+ return -2; \
+ case ERROR_TOO_MANY_RE_FIBERS: \
+ return -4; \
+ }
+
if (_yr_re_alloc_storage(&storage) != ERROR_SUCCESS)
return -2;
@@ -1730,19 +1754,17 @@ int yr_re_exec(
// extra byte which can't match anyways.
max_count = max_count - max_count % character_size;
-
count = 0;
- fiber = _yr_re_fiber_create(&storage->fiber_pool);
- fiber->ip = re_code;
+ error = _yr_re_fiber_create(&storage->fiber_pool, &fiber);
+ fail_if_error(error);
+ fiber->ip = re_code;
fibers.head = fiber;
fibers.tail = fiber;
error = _yr_re_fiber_sync(&fibers, &storage->fiber_pool, fiber);
-
- if (error != ERROR_SUCCESS)
- return -2;
+ fail_if_error(error);
while (fibers.head != NULL)
{
@@ -1952,15 +1974,13 @@ int yr_re_exec(
case ACTION_CONTINUE:
fiber->ip += 1;
error = _yr_re_fiber_sync(&fibers, &storage->fiber_pool, fiber);
- if (error != ERROR_SUCCESS)
- return -2;
+ fail_if_error(error);
break;
default:
next_fiber = fiber->next;
error = _yr_re_fiber_sync(&fibers, &storage->fiber_pool, fiber);
- if (error != ERROR_SUCCESS)
- return -2;
+ fail_if_error(error);
fiber = next_fiber;
}
}
@@ -1973,15 +1993,14 @@ int yr_re_exec(
if (flags & RE_FLAGS_SCAN && count < max_count)
{
- fiber = _yr_re_fiber_create(&storage->fiber_pool);
- fiber->ip = re_code;
+ error = _yr_re_fiber_create(&storage->fiber_pool, &fiber);
+ fail_if_error(error);
+ fiber->ip = re_code;
_yr_re_fiber_append(&fibers, fiber);
error = _yr_re_fiber_sync(&fibers, &storage->fiber_pool, fiber);
-
- if (error != ERROR_SUCCESS)
- return -2;
+ fail_if_error(error);
}
}
diff --git a/libyara/scan.c b/libyara/scan.c
index 7d6f06f..94c6424 100644
--- a/libyara/scan.c
+++ b/libyara/scan.c
@@ -781,6 +781,8 @@ int _yr_scan_verify_re_match(
case -3:
return ERROR_TOO_MANY_MATCHES;
case -4:
+ return ERROR_TOO_MANY_RE_FIBERS;
+ case -5:
return ERROR_INTERNAL_FATAL_ERROR;
}
@@ -812,6 +814,8 @@ int _yr_scan_verify_re_match(
case -3:
return ERROR_TOO_MANY_MATCHES;
case -4:
+ return ERROR_TOO_MANY_RE_FIBERS;
+ case -5:
return ERROR_INTERNAL_FATAL_ERROR;
}
}
--
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