[Forensics-changes] [yara] 23/192: Add yr_compiler_add_fd (#475)

Hilko Bengen bengen at moszumanska.debian.org
Sat Jul 1 10:31:42 UTC 2017


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

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

commit c48cea7b5363f06f4a87d1524655735ef3699b64
Author: Hilko Bengen <hillu at users.noreply.github.com>
Date:   Thu Sep 8 19:06:21 2016 +0200

    Add yr_compiler_add_fd (#475)
    
    This is a libc-neutral way to pass a file descriptor (Unix) or
    HANDLE (Windows) to the rule compiler as briefly discussed in #462.
---
 docs/capi.rst                   | 25 +++++++++++++++--------
 libyara/compiler.c              | 31 ++++++++++++++++++++++++++++
 libyara/include/yara/compiler.h |  8 ++++++++
 libyara/include/yara/lexer.h    |  4 ++++
 libyara/lexer.l                 | 44 ++++++++++++++++++++++++++++++++++++++++
 tests/data/true.yar             |  1 +
 tests/test-rules.c              | 45 +++++++++++++++++++++++++++++++++++++++++
 7 files changed, 150 insertions(+), 8 deletions(-)

diff --git a/docs/capi.rst b/docs/capi.rst
index 80f039c..b6f4db0 100644
--- a/docs/capi.rst
+++ b/docs/capi.rst
@@ -28,7 +28,7 @@ form. For that purpose you'll need a YARA compiler, which can be created with
 :c:func:`yr_compiler_create`. After being used, the compiler must be destroyed
 with :c:func:`yr_compiler_destroy`.
 
-You can use either :c:func:`yr_compiler_add_file` or
+You can use :c:func:`yr_compiler_add_file`, :c:func:`yr_compiler_add_fd`, or
 :c:func:`yr_compiler_add_string` to add one or more input sources to be
 compiled. Both of these functions receive an optional namespace. Rules added
 under the same namespace behaves as if they were contained within the same
@@ -36,12 +36,13 @@ source file or string, so, rule identifiers must be unique among all the sources
 sharing a namespace. If the namespace argument is ``NULL`` the rules are put
 in the *default* namespace.
 
-Both :c:func:`yr_compiler_add_file` and :c:func:`yr_compiler_add_string` return
+The :c:func:`yr_compiler_add_file`, :c:func:`yr_compiler_add_fd`, and
+:c:func:`yr_compiler_add_string` functions return
 the number of errors found in the source code. If the rules are correct they
 will return 0. For more detailed error information you must set a callback
 function by using :c:func:`yr_compiler_set_callback` before calling
-:c:func:`yr_compiler_add_file` or :c:func:`yr_compiler_add_string`. The
-callback function has the following prototype:
+any of the compiling functions. The callback function has the following
+prototype:
 
 .. code-block:: c
 
@@ -57,10 +58,10 @@ callback function has the following prototype:
 Possible values for ``error_level`` are ``YARA_ERROR_LEVEL_ERROR`` and
 ``YARA_ERROR_LEVEL_WARNING``. The arguments ``file_name`` and ``line_number``
 contains the file name and line number where the error or warning occurs.
-``file_name`` is the one passed to :c:func:`yr_compiler_add_file`. It can
-be ``NULL`` if you passed ``NULL`` or if you're using
-:c:func:`yr_compiler_add_string`. The ``user_data`` pointer is the same you
-passed to :c:func:`yr_compiler_set_callback`.
+``file_name`` is the one passed to :c:func:`yr_compiler_add_file` or
+:c:func:`yr_compiler_add_fd`. It can be ``NULL`` if you passed ``NULL`` or
+ if you're using :c:func:`yr_compiler_add_string`. The ``user_data`` pointer
+is the same you passed to :c:func:`yr_compiler_set_callback`.
 
 After you successfully added some sources you can get the compiled rules
 using the :c:func:`yr_compiler_get_rules()` function. You'll get a pointer to
@@ -398,6 +399,14 @@ Functions
   set to ``NULL``. Returns the number of errors found during compilation.
 
 
+.. c:function:: int yr_compiler_add_fd(YR_COMPILER* compiler, YR_FILE_DESCRIPTOR rules_fd, const char* namespace, const char* file_name)
+
+  Compile rules from a *file descriptor*. Rules are put into the specified *namespace*,
+  if *namespace* is ``NULL`` they will be put into the default namespace.
+  *file_name* is the name of the file for error reporting purposes and can be
+  set to ``NULL``. Returns the number of errors found during compilation.
+
+
 .. c:function:: int yr_compiler_add_string(YR_COMPILER* compiler, const char* string, const char* namespace_)
 
   Compile rules from a *string*. Rules are put into the specified *namespace*,
diff --git a/libyara/compiler.c b/libyara/compiler.c
index 40a761f..ea6c3b4 100644
--- a/libyara/compiler.c
+++ b/libyara/compiler.c
@@ -365,6 +365,37 @@ YR_API int yr_compiler_add_file(
 }
 
 
+YR_API int yr_compiler_add_fd(
+    YR_COMPILER* compiler,
+    YR_FILE_DESCRIPTOR rules_fd,
+    const char* namespace_,
+    const char* file_name)
+{
+  // Don't allow yr_compiler_add_fd() after
+  // yr_compiler_get_rules() has been called.
+
+  assert(compiler->compiled_rules_arena == NULL);
+
+  if (file_name != NULL)
+    _yr_compiler_push_file_name(compiler, file_name);
+
+  if (namespace_ != NULL)
+    compiler->last_result = _yr_compiler_set_namespace(compiler, namespace_);
+  else
+    compiler->last_result = _yr_compiler_set_namespace(compiler, "default");
+
+  if (compiler->last_result == ERROR_SUCCESS)
+  {
+    return yr_lex_parse_rules_fd(rules_fd, compiler);
+  }
+  else
+  {
+    compiler->errors++;
+    return compiler->errors;
+  }
+}
+
+
 YR_API int yr_compiler_add_string(
     YR_COMPILER* compiler,
     const char* rules_string,
diff --git a/libyara/include/yara/compiler.h b/libyara/include/yara/compiler.h
index f111373..ca1e7e7 100644
--- a/libyara/include/yara/compiler.h
+++ b/libyara/include/yara/compiler.h
@@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <yara/arena.h>
 #include <yara/hash.h>
 #include <yara/utils.h>
+#include <yara/filemap.h>
 
 
 #define YARA_ERROR_LEVEL_ERROR   0
@@ -172,6 +173,13 @@ YR_API int yr_compiler_add_file(
     const char* file_name);
 
 
+YR_API int yr_compiler_add_fd(
+    YR_COMPILER* compiler,
+    YR_FILE_DESCRIPTOR rules_fd,
+    const char* namespace_,
+    const char* file_name);
+
+
 YR_API int yr_compiler_add_string(
     YR_COMPILER* compiler,
     const char* rules_string,
diff --git a/libyara/include/yara/lexer.h b/libyara/include/yara/lexer.h
index e003fa7..2c6af19 100644
--- a/libyara/include/yara/lexer.h
+++ b/libyara/include/yara/lexer.h
@@ -143,3 +143,7 @@ int yr_lex_parse_rules_string(
 int yr_lex_parse_rules_file(
     FILE* rules_file,
     YR_COMPILER* compiler);
+
+int yr_lex_parse_rules_fd(
+    YR_FILE_DESCRIPTOR rules_fd,
+    YR_COMPILER* compiler);
diff --git a/libyara/lexer.l b/libyara/lexer.l
index b22af75..af45a20 100644
--- a/libyara/lexer.l
+++ b/libyara/lexer.l
@@ -49,6 +49,7 @@ with noyywrap then we can remove this pragma.
 #include <stdio.h>
 #include <string.h>
 #include <setjmp.h>
+#include <unistd.h>
 
 #include <yara/integers.h>
 #include <yara/lexer.h>
@@ -808,3 +809,46 @@ int yr_lex_parse_rules_file(
 
   return compiler->errors;
 }
+
+
+int yr_lex_parse_rules_fd(
+  YR_FILE_DESCRIPTOR rules_fd,
+  YR_COMPILER* compiler)
+{
+  yyscan_t yyscanner;
+
+  compiler->errors = 0;
+
+  if (setjmp(compiler->error_recovery) != 0)
+    return compiler->errors;
+
+  yylex_init(&yyscanner);
+
+  #if YYDEBUG
+  yydebug = 1;
+  #endif
+
+  char buf[1024];
+  int len;
+
+  yyset_extra(compiler, yyscanner);
+  while (1)
+  {
+    len = read(rules_fd, buf, sizeof(buf));
+    if (len < 0)
+    {
+      if (errno == EINTR)
+        continue;
+      else
+        break;
+    }
+    if (len == 0)
+      break;
+    yy_scan_bytes(buf, len, yyscanner);
+  }
+
+  yyparse(yyscanner, compiler);
+  yylex_destroy(yyscanner);
+
+  return compiler->errors;
+}
diff --git a/tests/data/true.yar b/tests/data/true.yar
new file mode 100644
index 0000000..55d91be
--- /dev/null
+++ b/tests/data/true.yar
@@ -0,0 +1 @@
+rule test { condition: true }
diff --git a/tests/test-rules.c b/tests/test-rules.c
index a305f06..a26c544 100644
--- a/tests/test-rules.c
+++ b/tests/test-rules.c
@@ -31,6 +31,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "blob.h"
 #include "util.h"
 
+#include <unistd.h>
+#include <fcntl.h>
 
 static void test_boolean_operators()
 {
@@ -1320,6 +1322,47 @@ void test_integer_functions()
 }
 
 
+void test_file_descriptor()
+{
+  YR_COMPILER* compiler = NULL;
+  YR_RULES* rules = NULL;
+  
+  int fd = open("tests/data/true.yar", O_RDONLY);
+  if (fd < 0) {
+    perror("open");
+    exit(EXIT_FAILURE);
+  }
+  if (yr_compiler_create(&compiler) != ERROR_SUCCESS)
+  {
+    perror("yr_compiler_create");
+    exit(EXIT_FAILURE);
+  }
+
+  if (yr_compiler_add_fd(compiler, fd, NULL, NULL) != 0) {
+    perror("yr_compiler_add_fd");
+    exit(EXIT_FAILURE);
+  }
+  
+  close(fd);
+
+  if (yr_compiler_get_rules(compiler, &rules) != ERROR_SUCCESS) {
+    perror("yr_compiler_add_fd");
+    exit(EXIT_FAILURE);
+  }
+
+  if (compiler)
+  {
+    yr_compiler_destroy(compiler);
+  }
+  if (rules)
+  {
+    yr_rules_destroy(rules);
+  }
+  
+  return;
+}
+
+
 int main(int argc, char** argv)
 {
   yr_initialize();
@@ -1359,6 +1402,8 @@ int main(int argc, char** argv)
   test_hash_module();
   #endif
 
+  test_file_descriptor();
+
   yr_finalize();
 
   return 0;

-- 
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