Control: tags -1 + patch

Please find attached a patch, build-tested only.
Description: Port to PCRE2.
Bug-Debian: https://bugs.debian.org/999968
Author: Yavor Doganov <ya...@gnu.org>
Forwarded: no
Last-Update: 2023-12-17
---

--- sagan-1.2.0.orig/configure.ac
+++ sagan-1.2.0/configure.ac
@@ -392,14 +392,25 @@
     CPPFLAGS="${CPPFLAGS} -I${with_libpcre_includes}"
 fi
 
-AC_CHECK_HEADER(pcre.h,,[AC_ERROR(pcre.h not found ...)])
+AC_CHECK_HEADER([pcre2.h], [], [AC_MSG_ERROR([pcre2.h not found ...])],
+[[#define PCRE2_CODE_UNIT_WIDTH 8
+]])
 
 if test "$with_libpcre_libraries" != "no"; then
     LDFLAGS="${LDFLAGS} -L${with_libpcre_libraries}"
 fi
 
 PCRE=""
-AC_CHECK_LIB(pcre, pcre_get_substring,, PCRE="no")
+LIBS="$LIBS -lpcre2-8"
+AC_MSG_CHECKING([for pcre library])
+AC_LINK_IFELSE(
+  [AC_LANG_PROGRAM([[#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
+]],
+[[pcre2_match_data *md = pcre2_match_data_create(4, NULL);]])],
+  [AC_MSG_RESULT([yes])],
+  [AC_MSG_RESULT([no])
+   PCRE="no"])
 if test "$PCRE" = "no"; then
     echo
     echo "   ERROR!  pcre library not found, go get it"
@@ -408,98 +419,44 @@
     exit 1
 fi
 
-# libpcre 8.35 (especially on debian) has a known issue that results in 
segfaults
-if test "$with_libpcre_libraries" = "no"; then
-    PKG_CHECK_MODULES(LIBPCREVERSION, [libpcre = 
8.35],[libpcre_buggy_found="yes"],[libprce_buggy_found="no"])
-    if test "$libpcre_buggy_found" = "yes"; then
-        echo
-        echo "   Warning! vulnerable libpcre version 8.35 found"
-        echo "   This version has a known issue that could result in segfaults"
-        echo "   please upgrade to a newer version of pcre which you can get 
from"
-        echo "   www.pcre.org. For more information, see issue #1693"
-        echo
-        echo "   Continuing for now with JIT disabled..."
-        echo
-    fi
-fi
-
-# To prevent duping the lib link we reset LIBS after this check. Setting 
action-if-found to NULL doesn't seem to work
-# see: http://blog.flameeyes.eu/2008/04/29/i-consider-ac_check_lib-harmful
-PCRE=""
-TMPLIBS="${LIBS}"
-AC_CHECK_LIB(pcre, pcre_dfa_exec,, PCRE="no")
-if test "$PCRE" = "no"; then
-    echo
-    echo "   ERROR!  pcre library was found but version was < 6.0"
-    echo "   please upgrade to a newer version of pcre which you can get from"
-    echo "   www.pcre.org."
-    echo
-    exit 1
-fi
-LIBS="${TMPLIBS}"
-
-AC_TRY_COMPILE([ #include <pcre.h> ],
-    [ int eo = 0; eo |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; ],
-    [ pcre_match_limit_recursion_available=yes ], [:]
-)
-
-if test "$pcre_match_limit_recursion_available" != "yes"; then
-    echo
-    echo "   Warning! pcre extra opt PCRE_EXTRA_MATCH_LIMIT_RECURSION not 
found"
-    echo "   This could lead to potential DoS please upgrade to pcre >= 6.5"
-    echo "   from www.pcre.org."
-    echo "   Continuing for now...."
-    echo
-    AC_DEFINE([NO_PCRE_MATCH_RLIMIT],[1],[Pcre 
PCRE_EXTRA_MATCH_LIMIT_RECURSION not available])
-fi
-
-TMPCFLAGS="${CFLAGS}"
-CFLAGS="-O0 -g -Werror -Wall"
-AC_TRY_COMPILE([ #include <pcre.h> ],
-    [ pcre_extra *extra = NULL; pcre_free_study(extra); ],
-    [ AC_DEFINE([HAVE_PCRE_FREE_STUDY], [1], [Pcre pcre_free_study 
supported])], [:]
-)
-CFLAGS="${TMPCFLAGS}"
-
-
 #enable support for PCRE-jit available since pcre-8.20
 AC_MSG_CHECKING(for PCRE JIT support)
-AC_TRY_COMPILE([ #include <pcre.h> ],
-    [
-    int jit = 0;
-    pcre_config(PCRE_CONFIG_JIT, &jit);
-    ],
+AC_RUN_IFELSE(
+  [AC_LANG_PROGRAM([[#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
+]],
+[[uint32_t jit = 0;
+  pcre2_config(PCRE2_CONFIG_JIT, &jit);
+  if (jit)
+    exit(EXIT_SUCCESS);
+  exit(EXIT_FAILURE);]])],
     [ pcre_jit_available=yes ], [ pcre_jit_available=no ]
     )
 
-# bug 1693, libpcre 8.35 is broken and debian jessie is still using that
-if test "$libpcre_buggy_found" = "yes"; then
-    pcre_jit_available="no, libpcre 8.35 blacklisted"
-fi
-
 
 if test "x$pcre_jit_available" = "xyes"; then
    AC_MSG_RESULT(yes)
    AC_DEFINE([PCRE_HAVE_JIT], [1], [Pcre with JIT compiler support enabled])
 
    AC_MSG_CHECKING(for PCRE JIT support usability)
-   AC_TRY_COMPILE([ #include <pcre.h> ],
-       [
-       const char* regexstr = "(a|b|c|d)";
-       pcre *re;
-       const char *error;
-       pcre_extra *extra;
-       int err_offset;
-       re = pcre_compile(regexstr,0, &error, &err_offset,NULL);
-       extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, &error);
-       if (extra == NULL)
-           exit(EXIT_FAILURE);
-       int jit = 0;
-       int ret = pcre_fullinfo(re, extra, PCRE_INFO_JIT, &jit);
-       if (ret != 0 || jit != 1)
+   AC_RUN_IFELSE(
+     [AC_LANG_PROGRAM([[#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
+]],
+       [[
+       PCRE2_SPTR regexstr = "(a|b|c|d)";
+       pcre2_code *re;
+       int error;
+       PCRE2_SIZE err_offset;
+       re = pcre2_compile(regexstr, PCRE2_ZERO_TERMINATED, 0,
+                          &error, &err_offset, NULL);
+       pcre2_jit_compile(re, PCRE2_JIT_COMPLETE);
+       size_t jit = 0;
+       int ret = pcre2_pattern_info(re, PCRE2_INFO_JITSIZE, &jit);
+       if (ret != 0 || jit == 0)
            exit(EXIT_FAILURE);
        exit(EXIT_SUCCESS);
-       ],
+       ]])],
        [ pcre_jit_works=yes ], [:]
    )
    if test "x$pcre_jit_works" != "xyes"; then
--- sagan-1.2.0.orig/src/processors/engine.c
+++ sagan-1.2.0/src/processors/engine.c
@@ -131,7 +131,7 @@
     int sagan_match = 0;       /* Used to determine if all has "matched" 
(content, pcre, meta_content, etc) */
 
     int rc = 0;
-    int ovector[PCRE_OVECCOUNT];
+    pcre2_match_data *ovector;
 
     int alter_num = 0;
     int meta_alter_num = 0;
@@ -221,6 +221,8 @@
 
     /* Search for matches */
 
+    ovector = pcre2_match_data_create(PCRE_OVECCOUNT, NULL);
+
     /* First we search for 'program' and such.   This way,  we don't waste CPU
      * time with pcre/content.  */
 
@@ -460,7 +462,7 @@
                                     for(z=0; z<rulestruct[b].pcre_count; z++)
                                         {
 
-                                            rc = pcre_exec( 
rulestruct[b].re_pcre[z], rulestruct[b].pcre_extra[z], 
SaganProcSyslog_LOCAL->syslog_message, 
(int)strlen(SaganProcSyslog_LOCAL->syslog_message), 0, 0, ovector, 
PCRE_OVECCOUNT);
+                                            rc = pcre2_match( 
rulestruct[b].re_pcre[z], (PCRE2_SPTR)SaganProcSyslog_LOCAL->syslog_message, 
strlen(SaganProcSyslog_LOCAL->syslog_message), 0, 0, ovector, NULL);
 
                                             if ( rc > 0 )
                                                 {
@@ -1425,6 +1427,7 @@
 
     free(processor_info_engine);
     free(lookup_cache);
+    pcre2_match_data_free(ovector);
 
 #ifdef HAVE_LIBLOGNORM
     if ( json_normalize != NULL )
--- sagan-1.2.0.orig/src/rules.c
+++ sagan-1.2.0/src/rules.c
@@ -41,7 +41,8 @@
 #include <string.h>
 #include <getopt.h>
 #include <time.h>
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 
 #include "version.h"
 
@@ -98,8 +99,8 @@
     sbool found = 0;
     sbool bad_rule = 0;
 
-    const char *error;
-    int erroffset;
+    int error;
+    PCRE2_SIZE erroffset;
 
     FILE *rulesfile;
     char ruleset_fullname[MAXPATH];
@@ -174,7 +175,7 @@
     int port_2_count=0;
 
     sbool pcreflag=0;
-    int pcreoptions=0;
+    uint32_t pcreoptions=0;
 
     int i=0;
     int d;
@@ -2091,25 +2092,25 @@
                                                 {
 
                                                 case 'i':
-                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE_CASELESS;
+                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE2_CASELESS;
                                                     break;
                                                 case 's':
-                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE_DOTALL;
+                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE2_DOTALL;
                                                     break;
                                                 case 'm':
-                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE_MULTILINE;
+                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE2_MULTILINE;
                                                     break;
                                                 case 'x':
-                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE_EXTENDED;
+                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE2_EXTENDED;
                                                     break;
                                                 case 'A':
-                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE_ANCHORED;
+                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE2_ANCHORED;
                                                     break;
                                                 case 'E':
-                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE_DOLLAR_ENDONLY;
+                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE2_DOLLAR_ENDONLY;
                                                     break;
                                                 case 'G':
-                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE_UNGREEDY;
+                                                    if ( pcreflag == 1 ) 
pcreoptions |= PCRE2_UNGREEDY;
                                                     break;
 
 
@@ -2147,28 +2148,20 @@
 
                             /* We store the compiled/study results.  This 
saves us some CPU time during searching - Champ Clark III - 02/01/2011 */
 
-                            
rulestruct[counters->rulecount].re_pcre[pcre_count] =  pcre_compile( pcrerule, 
pcreoptions, &error, &erroffset, NULL );
+                            
rulestruct[counters->rulecount].re_pcre[pcre_count] =  pcre2_compile( 
(PCRE2_SPTR)pcrerule, strlen(pcrerule), pcreoptions, &error, &erroffset, NULL );
 
 #ifdef PCRE_HAVE_JIT
 
                             if ( config->pcre_jit == 1 )
                                 {
-                                    pcreoptions |= PCRE_STUDY_JIT_COMPILE;
-                                }
-#endif
+                                    
pcre2_jit_compile(rulestruct[counters->rulecount].re_pcre[pcre_count], 
PCRE2_JIT_COMPLETE);
 
-                            
rulestruct[counters->rulecount].pcre_extra[pcre_count] = pcre_study( 
rulestruct[counters->rulecount].re_pcre[pcre_count], pcreoptions, &error);
-
-#ifdef PCRE_HAVE_JIT
-
-                            if ( config->pcre_jit == 1 )
-                                {
-                                    int jit = 0;
+                                    size_t jit = 0;
                                     rc = 0;
 
-                                    rc = 
pcre_fullinfo(rulestruct[counters->rulecount].re_pcre[pcre_count], 
rulestruct[counters->rulecount].pcre_extra[pcre_count], PCRE_INFO_JIT, &jit);
+                                    rc = 
pcre2_pattern_info(rulestruct[counters->rulecount].re_pcre[pcre_count], 
PCRE2_INFO_JITSIZE, &jit);
 
-                                    if (rc != 0 || jit != 1)
+                                    if (rc != 0 || jit == 0)
                                         {
                                             Sagan_Log(WARN, "[%s, line %d] 
PCRE JIT does not support regexp in %s at line %d (pcre: \"%s\"). Continuing 
without PCRE JIT enabled for this rule.", __FILE__, __LINE__, ruleset_fullname, 
linecount, pcrerule);
                                         }
--- sagan-1.2.0.orig/src/rules.h
+++ sagan-1.2.0/src/rules.h
@@ -79,8 +79,7 @@
     unsigned s_size_rule;
     char s_msg[MAX_SAGAN_MSG];
 
-    pcre *re_pcre[MAX_PCRE];
-    pcre_extra *pcre_extra[MAX_PCRE];
+    pcre2_code *re_pcre[MAX_PCRE];
 
     char s_content[MAX_CONTENT][256];
     char s_reference[MAX_REFERENCE][256];
--- sagan-1.2.0.orig/src/sagan.c
+++ sagan-1.2.0/src/sagan.c
@@ -42,7 +42,8 @@
 #include <getopt.h>
 #include <time.h>
 #include <signal.h>
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 #include <limits.h>
 #include <stdint.h>
 #include <inttypes.h>
@@ -224,6 +225,7 @@
 
     char *psyslogstring = NULL;
     char syslogstring[MAX_SYSLOGMSG];
+    char pcrever[24];
 
     signed char c;
     int rc=0;
@@ -894,7 +896,8 @@
     Sagan_Log(NORMAL, " \\/)\"(\\/     Version %s", VERSION);
     Sagan_Log(NORMAL, "  (_o_) Champ Clark III & The Quadrant InfoSec Team 
[quadrantsec.com]");
     Sagan_Log(NORMAL, "  /   \\/)      Copyright (C) 2009-2018 Quadrant 
Information Security, et al.");
-    Sagan_Log(NORMAL, " (|| ||)        Using PCRE version: %s", 
pcre_version());
+    pcre2_config(PCRE2_CONFIG_VERSION, pcrever);
+    Sagan_Log(NORMAL, " (|| ||)        Using PCRE version: %s", pcrever);
     Sagan_Log(NORMAL, "  oo-oo     Sagan is processing events.....");
     Sagan_Log(NORMAL, "");
 
--- sagan-1.2.0.orig/src/sagan.h
+++ sagan-1.2.0/src/sagan.h
@@ -32,7 +32,8 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <stddef.h>
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 #include <time.h>
 #include <arpa/inet.h>
 

Reply via email to