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 <[email protected]>
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>