Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package yara for openSUSE:Factory checked in 
at 2022-08-23 14:29:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yara (Old)
 and      /work/SRC/openSUSE:Factory/.yara.new.2083 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yara"

Tue Aug 23 14:29:38 2022 rev:16 rq:998699 version:4.2.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/yara/yara.changes        2022-07-19 
17:19:47.548401079 +0200
+++ /work/SRC/openSUSE:Factory/.yara.new.2083/yara.changes      2022-08-23 
14:29:49.723635422 +0200
@@ -1,0 +2,9 @@
+Tue Aug  9 20:24:40 UTC 2022 - Dirk M??ller <[email protected]>
+
+- update to 4.2.3: 
+  * BUGFIX: Fix security issue that can lead to arbitrary code execution 
+  (b77e4f4, b77e4f4). Thanks to ANSSI - CERT-FR for the report.
+  * BUGFIX: Fix incorrect logic in expressions like <quantifier> of
+    <string_set> in (start..end (#1757). 
+
+-------------------------------------------------------------------

Old:
----
  yara-4.2.2.tar.gz

New:
----
  yara-4.2.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ yara.spec ++++++
--- /var/tmp/diff_new_pack.NB6S5c/_old  2022-08-23 14:29:52.267640741 +0200
+++ /var/tmp/diff_new_pack.NB6S5c/_new  2022-08-23 14:29:52.271640749 +0200
@@ -18,7 +18,7 @@
 
 %global soname 9
 Name:           yara
-Version:        4.2.2
+Version:        4.2.3
 Release:        0
 Summary:        A malware identification and classification tool
 License:        BSD-3-Clause

++++++ yara-4.2.2.tar.gz -> yara-4.2.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yara-4.2.2/bazel/yara.bzl 
new/yara-4.2.3/bazel/yara.bzl
--- old/yara-4.2.2/bazel/yara.bzl       2022-06-30 11:06:13.000000000 +0200
+++ new/yara-4.2.3/bazel/yara.bzl       2022-08-08 13:29:28.000000000 +0200
@@ -61,6 +61,7 @@
 def yara_library(
         name,
         defines = [],
+        includes = [],
         modules = [],
         modules_srcs = [],
         deps = [],
@@ -195,7 +196,7 @@
             "libyara/include/yara/rules.h",
         ],
         copts = copts,
-        includes = [
+        includes = includes + [
             "libyara/modules",
             "libyara/include",
             "libyara",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yara-4.2.2/configure.ac new/yara-4.2.3/configure.ac
--- old/yara-4.2.2/configure.ac 2022-06-30 11:06:13.000000000 +0200
+++ new/yara-4.2.3/configure.ac 2022-08-08 13:29:28.000000000 +0200
@@ -1,4 +1,4 @@
-AC_INIT([yara], [4.2.2], [[email protected]])
+AC_INIT([yara], [4.2.3], [[email protected]])
 
 AM_SILENT_RULES([yes])
 AC_CONFIG_SRCDIR([cli/yara.c])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yara-4.2.2/libyara/exec.c 
new/yara-4.2.3/libyara/exec.c
--- old/yara-4.2.2/libyara/exec.c       2022-06-30 11:06:13.000000000 +0200
+++ new/yara-4.2.3/libyara/exec.c       2022-08-08 13:29:28.000000000 +0200
@@ -326,6 +326,22 @@
   return ERROR_SUCCESS;
 }
 
+// Global table that contains the "next" function for different types of
+// iterators. The reason for using this table is to avoid storing pointers
+// in the YARA's VM stack. Instead of the pointers we store an index within
+// this table.
+static YR_ITERATOR_NEXT_FUNC iter_next_func_table[] = {
+    iter_array_next,
+    iter_dict_next,
+    iter_int_range_next,
+    iter_int_enum_next,
+};
+
+#define ITER_NEXT_ARRAY     0
+#define ITER_NEXT_DICT      1
+#define ITER_NEXT_INT_RANGE 2
+#define ITER_NEXT_INT_ENUM  3
+
 int yr_execute_code(YR_SCAN_CONTEXT* context)
 {
   YR_DEBUG_FPRINTF(2, stderr, "+ %s() {\n", __FUNCTION__);
@@ -428,7 +444,7 @@
         pop(r1);
         r2.it->array_it.array = r1.o;
         r2.it->array_it.index = 0;
-        r2.it->next = iter_array_next;
+        r2.it->next_func_idx = ITER_NEXT_ARRAY;
         push(r2);
       }
 
@@ -449,7 +465,7 @@
         pop(r1);
         r2.it->dict_it.dict = r1.o;
         r2.it->dict_it.index = 0;
-        r2.it->next = iter_dict_next;
+        r2.it->next_func_idx = ITER_NEXT_DICT;
         push(r2);
       }
 
@@ -473,7 +489,7 @@
         pop(r1);
         r3.it->int_range_it.next = r1.i;
         r3.it->int_range_it.last = r2.i;
-        r3.it->next = iter_int_range_next;
+        r3.it->next_func_idx = ITER_NEXT_INT_RANGE;
         push(r3);
       }
 
@@ -499,7 +515,7 @@
       {
         r3.it->int_enum_it.count = r1.i;
         r3.it->int_enum_it.next = 0;
-        r3.it->next = iter_int_enum_next;
+        r3.it->next_func_idx = ITER_NEXT_INT_ENUM;
 
         for (int64_t i = r1.i; i > 0; i--)
         {
@@ -519,11 +535,22 @@
       // Loads the iterator in r1, but leaves the iterator in the stack.
       pop(r1);
       push(r1);
-      // The iterator's next function is responsible for pushing the next
-      // item in the stack, and a boolean indicating if there are more items
-      // to retrieve. The boolean will be at the top of the stack after
-      // calling "next".
-      result = r1.it->next(r1.it, &stack);
+
+      if (r1.it->next_func_idx <
+          sizeof(iter_next_func_table) / sizeof(YR_ITERATOR_NEXT_FUNC))
+      {
+        // The iterator's next function is responsible for pushing the next
+        // item in the stack, and a boolean indicating if there are more items
+        // to retrieve. The boolean will be at the top of the stack after
+        // calling "next".
+        result = iter_next_func_table[r1.it->next_func_idx](r1.it, &stack);
+      }
+      else
+      {
+        // next_func_idx is outside the valid range, this should not happend.
+        result = ERROR_INTERNAL_FATAL_ERROR;
+      }
+
       stop = (result != ERROR_SUCCESS);
       break;
 
@@ -1388,10 +1415,24 @@
       {
         YR_DEBUG_FPRINTF(2, stderr, "- case OP_OF: // %s()\n", __FUNCTION__);
 
+        // Quantifier is "all"
         if (is_undef(r2))
+        {
           r1.i = found >= count ? 1 : 0;
+        }
+        // Quantifier is 0 or none. This is a special case in which we want
+        // exactly 0 strings matching. More information at:
+        // https://github.com/VirusTotal/yara/issues/1695
+        else if (r2.i == 0)
+        {
+          r1.i = found == 0 ? 1 : 0;
+        }
+        // In all other cases the number of strings matching should be at
+        // least the amount specified by the quantifier.
         else
+        {
           r1.i = found >= r2.i ? 1 : 0;
+        }
       }
       else  // OP_OF_PERCENT
       {
@@ -1416,12 +1457,23 @@
 
       found = 0;
       count = 0;
-      pop(r2);
-      pop(r1);
-      ensure_defined(r1);
-      ensure_defined(r2);
 
-      pop(r3);
+      pop(r2);  // Offset range end
+      pop(r1);  // Offset range start
+      pop(r3);  // First string
+
+      // If any of the range boundaries are undefined the result is also
+      // undefined, be we need to unwind the stack first.
+      if (is_undef(r1) || is_undef(r2))
+      {
+        // Remove all the strings.
+        while (!is_undef(r3)) pop(r3);
+        // Remove the quantifier at the bottom of the stack.
+        pop(r3);
+        r1.i = YR_UNDEFINED;
+        push(r1);
+        break;
+      }
 
       while (!is_undef(r3))
       {
@@ -1432,6 +1484,7 @@
 
         while (match != NULL)
         {
+          // String match within range start and range end?
           if (match->base + match->offset >= r1.i &&
               match->base + match->offset <= r2.i)
           {
@@ -1439,6 +1492,9 @@
             break;
           }
 
+          // If current match is past range end, we can stop as matches
+          // are sortred by offset in increasing order, so all remaining
+          // matches are part the range end too.
           if (match->base + match->offset > r1.i)
             break;
 
@@ -1449,11 +1505,26 @@
         pop(r3);
       }
 
-      pop(r1);
-      if (is_undef(r1))
+      pop(r2);  // Quantifier X in expressions like "X of string_set in range"
+
+      // Quantifier is "all".
+      if (is_undef(r2))
+      {
         r1.i = found >= count ? 1 : 0;
+      }
+      // Quantifier is 0 or none. This is a special case in which we want
+      // exactly 0 strings matching. More information at:
+      // https://github.com/VirusTotal/yara/issues/1695
+      else if (r2.i == 0)
+      {
+        r1.i = found == 0 ? 1 : 0;
+      }
+      // In all other cases the number of strings matching should be at least
+      // the amount specified by the quantifier.
       else
-        r1.i = found >= r1.i ? 1 : 0;
+      {
+        r1.i = found >= r2.i ? 1 : 0;
+      }
 
       push(r1);
       break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yara-4.2.2/libyara/include/yara/libyara.h 
new/yara-4.2.3/libyara/include/yara/libyara.h
--- old/yara-4.2.2/libyara/include/yara/libyara.h       2022-06-30 
11:06:13.000000000 +0200
+++ new/yara-4.2.3/libyara/include/yara/libyara.h       2022-08-08 
13:29:28.000000000 +0200
@@ -34,7 +34,7 @@
 
 #define YR_MAJOR_VERSION 4
 #define YR_MINOR_VERSION 2
-#define YR_MICRO_VERSION 2
+#define YR_MICRO_VERSION 3
 
 #define version_str(s)  _version_str(s)
 #define _version_str(s) #s
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yara-4.2.2/libyara/include/yara/types.h 
new/yara-4.2.3/libyara/include/yara/types.h
--- old/yara-4.2.2/libyara/include/yara/types.h 2022-06-30 11:06:13.000000000 
+0200
+++ new/yara-4.2.3/libyara/include/yara/types.h 2022-08-08 13:29:28.000000000 
+0200
@@ -397,12 +397,21 @@
 #pragma warning(disable : 4200)
 #endif
 
+// The RE structure is embedded in the YARA's VM instruction flow, which
+// means that its alignment is not guaranteed. For this reason the it must
+// be a "packed" structure, in order to prevent alignment issues in platforms
+// with strict alignment constraints.
+#pragma pack(push)
+#pragma pack(1)
+
 struct RE
 {
   uint32_t flags;
   uint8_t code[0];
 };
 
+#pragma pack(pop)
+
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
@@ -979,7 +988,8 @@
 
 struct YR_ITERATOR
 {
-  YR_ITERATOR_NEXT_FUNC next;
+  // Index of the next function within the iter_next_func_table global array.
+  int next_func_idx;
 
   union
   {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yara-4.2.2/tests/test-rules.c 
new/yara-4.2.3/tests/test-rules.c
--- old/yara-4.2.2/tests/test-rules.c   2022-06-30 11:06:13.000000000 +0200
+++ new/yara-4.2.3/tests/test-rules.c   2022-08-08 13:29:28.000000000 +0200
@@ -631,6 +631,28 @@
        }",
       "foobarbaz" TEXT_1024_BYTES);
 
+  // https://github.com/VirusTotal/yara/issues/1695
+  assert_false_rule(
+      "rule test {\n\
+         strings:\n\
+             $a = \"AXS\"\n\
+             $b = \"ERS\"\n\
+         condition:\n\
+             none of them in (0..10)\n\
+       }",
+      "AXSERS" TEXT_1024_BYTES);
+
+  // https://github.com/VirusTotal/yara/issues/1757
+  assert_false_rule(
+      "rule test {\n\
+         strings:\n\
+             $a = \"foo\"\n\
+             $b = \"foo\"\n\
+         condition:\n\
+             none of them in (0..1)\n\
+       }",
+      "foo");
+
   // https://github.com/VirusTotal/yara/issues/1660
   assert_false_rule(
       "rule test {\n\
@@ -1724,6 +1746,28 @@
        }",
       "mississippi");
 
+  // If one of the bounds can not be determined statically it isn't an error.
+  assert_true_rule(
+      "rule test { \
+      strings: \
+        $a = \"AXSERS\" \
+      condition: \
+        true or any of them in (0..filesize-100) \
+    }",
+      TEXT_1024_BYTES);
+
+  // Make sure that an undefined range boundary returns an undefined value,
+  // which translates to false.
+  assert_false_rule(
+      "import \"tests\" \
+        rule test { \
+                     strings: \
+                             $a = \"missi\" \
+                     condition: \
+                             any of them in (0..tests.undefined.i) \
+           }",
+      "mississippi");
+
   YR_DEBUG_FPRINTF(1, stderr, "} // %s()\n", __FUNCTION__);
 }
 
@@ -1952,6 +1996,16 @@
       }",
       NULL);
 
+  // Test case for https://github.com/VirusTotal/yara/issues/1729
+  assert_true_rule(
+      "rule test { \
+        strings: \
+          $a = \"abcde\" \
+        condition: \
+          for any n in (1..10) : ( n of ($a*) ) \
+      }",
+      "abcde");
+
   YR_DEBUG_FPRINTF(1, stderr, "} // %s()\n", __FUNCTION__);
 }
 

Reply via email to