Control: tags -1 + patch Please find attached a patch (it applies to the latest upstream release 2.9.20 as well but not to the 3.x series).
Description: Port to PCRE2. Bug-Debian: https://bugs.debian.org/999956 Author: Yavor Doganov <ya...@gnu.org> Forwarded: no Last-Update: 2024-01-02 ---
--- snort-2.9.15.1.orig/configure.in +++ snort-2.9.15.1/configure.in @@ -465,19 +465,21 @@ CPPFLAGS="${CPPFLAGS} -I${with_libpcre_includes}" ICONFIGFLAGS="${ICONFIGFLAGS} -I${with_libpcre_includes}" else - CPPFLAGS="${CPPFLAGS} `pcre-config --cflags`" + CPPFLAGS="${CPPFLAGS} `pcre2-config --cflags`" fi if test "x$with_libpcre_libraries" != "xno"; then LDFLAGS="${LDFLAGS} -L${with_libpcre_libraries}" else - LDFLAGS="${LDFLAGS} `pcre-config --libs`" + LDFLAGS="${LDFLAGS} `pcre2-config --libs8`" fi # PCRE configuration (required) # Verify that we have the headers PCRE_H="" -AC_CHECK_HEADERS(pcre.h,, PCRE_H="no") +AC_CHECK_HEADERS([pcre2.h], [], [PCRE_H="no"], [[ +#define PCRE2_CODE_UNIT_WIDTH 8 +]]) if test "x$PCRE_H" = "xno"; then echo echo " ERROR! Libpcre header not found." @@ -487,36 +489,13 @@ # Verify that we have the library PCRE_L="" -pcre_version_six="" -AC_CHECK_LIB(pcre, pcre_compile, ,PCRE_L="no") +AC_CHECK_LIB([pcre2-8], [pcre2_compile_8], [], [PCRE_L="no"]) if test "x$PCRE_L" = "xno"; then echo echo " ERROR! Libpcre library not found." echo " Get it from http://www.pcre.org" echo exit 1 -else - AC_MSG_CHECKING(for libpcre version 6.0 or greater) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pcre.h>]], [[ - #if (PCRE_MAJOR < 6) - #error "Version failure" - #else - int a, b = 0, c = 0, d = 0; - pcre *tmp = NULL; - a = pcre_copy_named_substring(tmp, "", &b, c, "", "", d); - #endif - ]])],[pcre_version_six="yes"],[pcre_version_six="no"]) -fi - -if test "x$pcre_version_six" != "xyes"; then - AC_MSG_RESULT(no) - echo - echo " ERROR! Libpcre library version >= 6.0 not found." - echo " Get it from http://www.pcre.org" - echo - exit 1 -else - AC_MSG_RESULT(yes) fi # OPENSSL SHA configuration (optional) --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h +++ snort-2.9.15.1/src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h @@ -30,7 +30,8 @@ #ifndef SF_SNORT_PLUGIN_API_H_ #define SF_SNORT_PLUGIN_API_H_ -#include "pcre.h" +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "stdio.h" #ifndef WIN32 @@ -226,7 +227,7 @@ { char *expr; void *compiled_expr; - void *compiled_extra; + void *ctxt; uint32_t compile_flags; uint32_t flags; /* must include a CONTENT_BUF_X */ int32_t offset; @@ -507,7 +508,7 @@ ENGINE_LINKAGE void setAltDetect(uint8_t *buf, uint16_t altLen); ENGINE_LINKAGE int pcreExecWrapper(const PCREInfo *pcre_info, const char *buf, int len, int start_offset, - int options, int *ovector, int ovecsize); + int options, size_t *ovector, int ovecsize); static inline int invertMatchResult(int retVal) { --- snort-2.9.15.1.orig/src/detection-plugins/sp_pcre.h +++ snort-2.9.15.1/src/detection-plugins/sp_pcre.h @@ -49,17 +49,18 @@ void SetupPcre(void); -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> typedef struct _PcreData { - pcre *re; /* compiled regex */ - pcre_extra *pe; /* studied regex foo */ - int options; /* sp_pcre specfic options (relative & inverse) */ + pcre2_code *re; /* compiled regex */ + pcre2_match_context *ctxt; + uint32_t options; /* sp_pcre specfic options (relative & inverse) */ char *expression; - uint32_t search_offset; + PCRE2_SIZE search_offset; } PcreData; -void PcreCapture(struct _SnortConfig *sc, const void *code, const void *extra); +void PcreCapture(struct _SnortConfig *sc, const void *code); void PcreFree(void *d); uint32_t PcreHash(void *d); int PcreCompare(void *l, void *r); --- snort-2.9.15.1.orig/src/detection-plugins/sp_pcre.c +++ snort-2.9.15.1/src/detection-plugins/sp_pcre.c @@ -46,7 +46,8 @@ #include "sp_pcre.h" -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "snort.h" #include "profiler.h" @@ -77,8 +78,8 @@ PcreData *data = (PcreData *)d; free(data->expression); - free(data->re); - free(data->pe); + pcre2_code_free(data->re); + pcre2_match_context_free(data->ctxt); free(data); } @@ -161,8 +162,8 @@ pcre_dup->expression = pcre_src->expression; pcre_dup->options = pcre_src->options; pcre_dup->search_offset = 0; - pcre_dup->pe = pcre_src->pe; pcre_dup->re = pcre_src->re; + pcre_dup->ctxt = pcre_src->ctxt; } int PcreAdjustRelativeOffsets(PcreData *pcre, uint32_t search_offset) @@ -207,8 +208,6 @@ if (sc->pcre_ovector_size > s_ovector_max) s_ovector_max = sc->pcre_ovector_size; - - sc->pcre_ovector = (int *) SnortAlloc(s_ovector_max*sizeof(int)); } #if SNORT_RELOAD @@ -218,12 +217,12 @@ } #endif -void PcreCapture(struct _SnortConfig *sc, const void *code, const void *extra) +void PcreCapture(struct _SnortConfig *sc, const void *code) { int tmp_ovector_size = 0; - pcre_fullinfo((const pcre *)code, (const pcre_extra *)extra, - PCRE_INFO_CAPTURECOUNT, &tmp_ovector_size); + pcre2_pattern_info((pcre2_code *)code, + PCRE2_INFO_CAPTURECOUNT, &tmp_ovector_size); if (tmp_ovector_size > sc->pcre_ovector_size) sc->pcre_ovector_size = tmp_ovector_size; @@ -268,10 +267,10 @@ if (pcre_data->expression) free(pcre_data->expression); - if (pcre_data->pe) - free(pcre_data->pe); if (pcre_data->re) - free(pcre_data->re); + pcre2_code_free(pcre_data->re); + if (pcre_data->ctxt) + pcre2_match_context_free(pcre_data->ctxt); free(pcre_data); pcre_data = pcre_dup; @@ -305,12 +304,13 @@ void SnortPcreParse(struct _SnortConfig *sc, char *data, PcreData *pcre_data, OptTreeNode *otn) { - const char *error; + PCRE2_UCHAR error[120]; char *re, *free_me; char *opts; char delimit = '/'; - int erroffset; - int compile_flags = 0; + PCRE2_SIZE erroffset; + int err; + uint32_t compile_flags = 0; unsigned http = 0; if(data == NULL) @@ -381,17 +381,17 @@ /* process any /regex/ismxR options */ while(*opts != '\0') { switch(*opts) { - case 'i': compile_flags |= PCRE_CASELESS; break; - case 's': compile_flags |= PCRE_DOTALL; break; - case 'm': compile_flags |= PCRE_MULTILINE; break; - case 'x': compile_flags |= PCRE_EXTENDED; break; + case 'i': compile_flags |= PCRE2_CASELESS; break; + case 's': compile_flags |= PCRE2_DOTALL; break; + case 'm': compile_flags |= PCRE2_MULTILINE; break; + case 'x': compile_flags |= PCRE2_EXTENDED; break; /* * these are pcre specific... don't work with perl */ - case 'A': compile_flags |= PCRE_ANCHORED; break; - case 'E': compile_flags |= PCRE_DOLLAR_ENDONLY; break; - case 'G': compile_flags |= PCRE_UNGREEDY; break; + case 'A': compile_flags |= PCRE2_ANCHORED; break; + case 'E': compile_flags |= PCRE2_DOLLAR_ENDONLY; break; + case 'G': compile_flags |= PCRE2_UNGREEDY; break; /* * these are snort specific don't work with pcre or perl @@ -424,77 +424,32 @@ /* now compile the re */ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre: compiling %s\n", re);); - pcre_data->re = pcre_compile(re, compile_flags, &error, &erroffset, NULL); + pcre_data->re = pcre2_compile((PCRE2_SPTR)re, PCRE2_ZERO_TERMINATED, compile_flags, &err, &erroffset, NULL); if(pcre_data->re == NULL) { + pcre2_get_error_message(err, error, sizeof(error)); FatalError("%s(%d) : pcre compile of \"%s\" failed at offset " - "%d : %s\n", file_name, file_line, re, erroffset, error); + "%zu : %s\n", file_name, file_line, re, erroffset, error); } - /* now study it... */ - pcre_data->pe = pcre_study(pcre_data->re, 0, &error); - - if (pcre_data->pe) + if (!(pcre_data->ctxt = pcre2_match_context_create(NULL))) { - if ((ScPcreMatchLimitNewConf(sc) != -1) && !(pcre_data->options & SNORT_OVERRIDE_MATCH_LIMIT)) - { - if (pcre_data->pe->flags & PCRE_EXTRA_MATCH_LIMIT) - { - pcre_data->pe->match_limit = ScPcreMatchLimitNewConf(sc); - } - else - { - pcre_data->pe->flags |= PCRE_EXTRA_MATCH_LIMIT; - pcre_data->pe->match_limit = ScPcreMatchLimitNewConf(sc); - } - } - -#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION - if ((ScPcreMatchLimitRecursionNewConf(sc) != -1) && !(pcre_data->options & SNORT_OVERRIDE_MATCH_LIMIT)) - { - if (pcre_data->pe->flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) - { - pcre_data->pe->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc); - } - else - { - pcre_data->pe->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; - pcre_data->pe->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc); - } - } -#endif + FatalError("%s(%d) : pcre2_match_context_create failed\n", file_name, + file_line); } - else + if ((ScPcreMatchLimitNewConf(sc) != -1) && !(pcre_data->options & SNORT_OVERRIDE_MATCH_LIMIT)) { - if (!(pcre_data->options & SNORT_OVERRIDE_MATCH_LIMIT) && - ((ScPcreMatchLimitNewConf(sc) != -1) || (ScPcreMatchLimitRecursionNewConf(sc) != -1))) - { - pcre_data->pe = (pcre_extra *)SnortAlloc(sizeof(pcre_extra)); - if (ScPcreMatchLimitNewConf(sc) != -1) - { - pcre_data->pe->flags |= PCRE_EXTRA_MATCH_LIMIT; - pcre_data->pe->match_limit = ScPcreMatchLimitNewConf(sc); - } - -#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION - if (ScPcreMatchLimitRecursionNewConf(sc) != -1) - { - pcre_data->pe->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; - pcre_data->pe->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc); - } -#endif - } + pcre2_set_match_limit(pcre_data->ctxt, ScPcreMatchLimitNewConf(sc)); } - if(error != NULL) + if ((ScPcreMatchLimitRecursionNewConf(sc) != -1) && !(pcre_data->options & SNORT_OVERRIDE_MATCH_LIMIT)) { - FatalError("%s(%d) : pcre study failed : %s\n", file_name, - file_line, error); + pcre2_set_depth_limit(pcre_data->ctxt, ScPcreMatchLimitRecursionNewConf(sc)); } - PcreCapture(sc, pcre_data->re, pcre_data->pe); + PcreCapture(sc, pcre_data->re); PcreCheckAnchored(pcre_data); @@ -513,12 +468,12 @@ void PcreCheckAnchored(PcreData *pcre_data) { int rc; - unsigned long int options = 0; + uint32_t options = 0; - if ((pcre_data == NULL) || (pcre_data->re == NULL) || (pcre_data->pe == NULL)) + if ((pcre_data == NULL) || (pcre_data->re == NULL)) return; - rc = pcre_fullinfo(pcre_data->re, pcre_data->pe, PCRE_INFO_OPTIONS, (void *)&options); + rc = pcre2_pattern_info(pcre_data->re, PCRE2_INFO_ALLOPTIONS, &options); switch (rc) { /* pcre_fullinfo fails for the following: @@ -533,24 +488,24 @@ /* This is the success code */ break; - case PCRE_ERROR_NULL: - FatalError("%s(%d) pcre_fullinfo: code and/or where were NULL.\n", + case PCRE2_ERROR_NULL: + FatalError("%s(%d) pcre2_pattern_info: code and/or where were NULL.\n", __FILE__, __LINE__); - case PCRE_ERROR_BADMAGIC: - FatalError("%s(%d) pcre_fullinfo: compiled code didn't have " + case PCRE2_ERROR_BADMAGIC: + FatalError("%s(%d) pcre2_pattern_info: compiled code didn't have " "correct magic.\n", __FILE__, __LINE__); - case PCRE_ERROR_BADOPTION: - FatalError("%s(%d) pcre_fullinfo: option type is invalid.\n", + case PCRE2_ERROR_BADOPTION: + FatalError("%s(%d) pcre2_pattern_info: option type is invalid.\n", __FILE__, __LINE__); default: - FatalError("%s(%d) pcre_fullinfo: Unknown error code.\n", + FatalError("%s(%d) pcre2_pattern_info: Unknown error code.\n", __FILE__, __LINE__); } - if ((options & PCRE_ANCHORED) && !(options & PCRE_MULTILINE)) + if ((options & PCRE2_ANCHORED) && !(options & PCRE2_MULTILINE)) { /* This means that this pcre rule option shouldn't be reevaluted * even if any of it's relative children should fail to match. @@ -579,6 +534,7 @@ int start_offset, int *found_offset) { + pcre2_match_data *md; int matched; int result; @@ -596,14 +552,14 @@ *found_offset = -1; - result = pcre_exec(pcre_data->re, /* result of pcre_compile() */ - pcre_data->pe, /* result of pcre_study() */ - buf, /* the subject string */ - len, /* the length of the subject string */ - start_offset, /* start at offset 0 in the subject */ - 0, /* options(handled at compile time */ - snort_conf->pcre_ovector, /* vector for substring information */ - snort_conf->pcre_ovector_size);/* number of elements in the vector */ + md = pcre2_match_data_create(snort_conf->pcre_ovector_size, NULL); + result = pcre2_match(pcre_data->re, /* result of pcre_compile() */ + (PCRE2_SPTR)buf,/* the subject string */ + len, /* the length of the subject string */ + start_offset, /* start at offset 0 in the subject */ + 0, /* options(handled at compile time */ + md, /* match data */ + pcre_data->ctxt); /* match context */ if(result >= 0) { @@ -620,18 +576,20 @@ * * In Snort's case, the ovector size only allows for the first pair and a single int for scratch space. */ - *found_offset = snort_conf->pcre_ovector[1]; + snort_conf->pcre_ovector = pcre2_get_ovector_pointer(md); + *found_offset = (int)snort_conf->pcre_ovector[1]; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Setting Doe_ptr and found_offset: %p %d\n", doe_ptr, found_offset);); } - else if(result == PCRE_ERROR_NOMATCH) + else if(result == PCRE2_ERROR_NOMATCH) { matched = 0; } else { - DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre_exec error : %d \n", result);); + DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre2_match error : %d \n", result);); + pcre2_match_data_free(md); return 0; } @@ -640,6 +598,7 @@ { matched = !matched; } + pcre2_match_data_free(md); return matched; } --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_engine/examples/bug35218.c +++ snort-2.9.15.1/src/dynamic-plugins/sf_engine/examples/bug35218.c @@ -26,7 +26,8 @@ #include "config.h" #endif -#include "pcre.h" +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "sf_snort_plugin_api.h" #include "sf_snort_packet.h" @@ -101,8 +102,8 @@ { "^Content-Transfer-Encoding:\\s*base64\\s*$", /* pattern to search for */ NULL, /* compiled_expr */ - 0, /* compiled_extra */ - PCRE_CASELESS | PCRE_MULTILINE, /* compile_flags */ + NULL, /* match context */ + PCRE2_CASELESS | PCRE2_MULTILINE, /* compile_flags */ CONTENT_BUF_RAW, /* flags: must include a CONTENT_BUF_X */ 0 /* offset */ }; @@ -123,8 +124,8 @@ { "^Content-Transfer-Encoding:\\s*base64\\s*$", /* pattern to search for */ NULL, /* compiled_expr */ - 0, /* compiled_extra */ - PCRE_CASELESS | PCRE_MULTILINE, /* compile_flags */ + NULL, /* match context */ + PCRE2_CASELESS | PCRE2_MULTILINE, /* compile_flags */ CONTENT_BUF_RAW | CONTENT_RELATIVE, /* flags: must include a CONTENT_BUF_X */ 0 /* offset */ }; --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_engine/examples/3682.c +++ snort-2.9.15.1/src/dynamic-plugins/sf_engine/examples/3682.c @@ -9,7 +9,8 @@ #include "config.h" #endif -#include "pcre.h" +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "sf_snort_plugin_api.h" #include "sf_snort_packet.h" #include "detection_lib_meta.h" @@ -107,8 +108,8 @@ { "Content-Type\\x3A\\s+audio\\/(x-wav|mpeg|x-midi)", /* expression */ NULL, /* Holder for compiled expr */ - NULL, /* Holder for compiled expr extra flags */ - PCRE_CASELESS, /* Compile Flags */ + NULL, /* Match context */ + PCRE2_CASELESS, /* Compile Flags */ CONTENT_BUF_NORMALIZED, /* Flags */ 0 /* offset */ }; @@ -152,8 +153,8 @@ { "filename=[\\x22\\x27]?.{1,221}\\.(vbs|exe|scr|pif|bat)", /* expression */ NULL, /* Holder for compiled expr */ - NULL, /* Holder for compiled expr extra flags */ - PCRE_CASELESS, /* Compile Flags */ + NULL, /* Match context */ + PCRE2_CASELESS, /* Compile Flags */ CONTENT_BUF_NORMALIZED, /* Flags */ 0 /* offset */ }; --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_engine/examples/bug31842.c +++ snort-2.9.15.1/src/dynamic-plugins/sf_engine/examples/bug31842.c @@ -25,7 +25,8 @@ #include "config.h" #endif -#include "pcre.h" +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "sf_snort_plugin_api.h" #include "sf_snort_packet.h" @@ -93,8 +94,8 @@ { "^Proxy-Authorization:\\s*NTLM\\s+", /* pattern to search for */ NULL, /* holder for compiled pattern */ - NULL, /* holder for compiled pattern flags */ - PCRE_CASELESS | PCRE_DOTALL | PCRE_MULTILINE, /* compile flags */ + NULL, /* match context */ + PCRE2_CASELESS | PCRE2_DOTALL | PCRE2_MULTILINE, /* compile flags */ CONTENT_BUF_NORMALIZED, /* content flags */ 0 /* offset */ }; --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_engine/examples/sid1902.c +++ snort-2.9.15.1/src/dynamic-plugins/sf_engine/examples/sid1902.c @@ -12,7 +12,8 @@ #include "config.h" #endif -#include "pcre.h" +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "sf_snort_plugin_api.h" #include "sf_snort_packet.h" @@ -63,8 +64,8 @@ { "\\sLSUB\\s[^\\n]*?\\s\\{", /* pattern */ NULL, /* holder for compiled pattern */ - NULL, /* holder for compiled pattern flags */ - PCRE_CASELESS|PCRE_DOTALL|PCRE_MULTILINE, /* compile flags */ + NULL, /* match context */ + PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_MULTILINE, /* compile flags */ CONTENT_BUF_NORMALIZED, /* content flags */ 0 /* offset */ }; --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_engine/examples/sid2389.c +++ snort-2.9.15.1/src/dynamic-plugins/sf_engine/examples/sid2389.c @@ -6,7 +6,8 @@ #include "config.h" #endif -#include "pcre.h" +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "sf_snort_plugin_api.h" #include "detection_lib_meta.h" @@ -117,8 +118,8 @@ { /* PCRE */ "^RNTO\\s[^\\n]{100}", /* expression */ NULL, /* Holder for compiled expr */ - NULL, /* Holder for compiled expr extra flags */ - PCRE_DOTALL | PCRE_MULTILINE | PCRE_CASELESS, /* Compile Flags */ + NULL, /* Match context */ + PCRE2_DOTALL | PCRE2_MULTILINE | PCRE2_CASELESS, /* Compile Flags */ CONTENT_BUF_NORMALIZED, /* Flags */ 0 /* offset */ }; --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_engine/examples/36733.c +++ snort-2.9.15.1/src/dynamic-plugins/sf_engine/examples/36733.c @@ -25,7 +25,8 @@ #include "config.h" #endif -#include "pcre.h" +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "sf_snort_plugin_api.h" #include "sf_snort_packet.h" #include "web-misc_base64_decode.h" @@ -84,8 +85,8 @@ { "^Authorization:\\s*Basic\\s+", /* pattern (now in snort content format) */ 0, /* compiled expression */ - 0, /* compiled extra */ - PCRE_CASELESS | PCRE_MULTILINE, /* compile flags */ + NULL, /* match context */ + PCRE2_CASELESS | PCRE2_MULTILINE, /* compile flags */ CONTENT_BUF_NORMALIZED, /* flags */ // XXX - need to add CONTENT_FAST_PATTERN support 0 /* offset */ }; @@ -191,7 +192,7 @@ // manual pcre stuff int result; - int ovector[3]; // Needs to be a multiple of 3 + PCRE2_SIZE ovector[3]; // Needs to be a multiple of 3 if(sp == NULL) return RULE_NOMATCH; @@ -245,7 +246,7 @@ 0, // start offset 0, // options (handled at compile time) ovector, // ovector for storing result substrings - sizeof(ovector)/sizeof(int)); // size of ovector + sizeof(ovector)/sizeof(PCRE2_SIZE)); // size of ovector //DEBUG_WRAP(printf("result = %d\n", result)); --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_engine/examples/web-client_test.c +++ snort-2.9.15.1/src/dynamic-plugins/sf_engine/examples/web-client_test.c @@ -89,8 +89,8 @@ { "IIS 7\\x2e5 Detailed Error - 404\\x2e0 - Not Found", /* pattern */ NULL, /* holder for compiled pattern */ - NULL, /* holder for compiled pattern flags */ - PCRE_CASELESS, /* compile flags */ + NULL, /* match context */ + PCRE2_CASELESS, /* compile flags */ CONTENT_BUF_NORMALIZED, /* content flags */ 0 /* offset */ }; @@ -260,8 +260,8 @@ { "SignUrl=[^\\x26\\s]*[\\x22\\x27\\x28\\x29\\x3C\\x3E]", /* pattern */ NULL, /* holder for compiled pattern */ - NULL, /* holder for compiled pattern flags */ - PCRE_CASELESS, /* compile flags */ + NULL, /* match context */ + PCRE2_CASELESS, /* compile flags */ CONTENT_BUF_URI, /* content flags */ 0 /* offset */ }; @@ -432,8 +432,8 @@ { "SignUrl=[^\\\\x26\\\\s]*[\\\\x22\\\\x27\\\\x28\\\\x29\\\\x3C\\\\x3E]", /* pattern */ NULL, /* holder for compiled pattern */ - NULL, /* holder for compiled pattern flags */ - PCRE_CASELESS, /* compile flags */ + NULL, /* match context */ + PCRE2_CASELESS, /* compile flags */ CONTENT_BUF_URI, /* content flags */ 0 /* offset */ }; --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c +++ snort-2.9.15.1/src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c @@ -31,7 +31,8 @@ #include "config.h" #endif -#include "pcre.h" +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "sf_types.h" #include "snort_debug.h" #include "sf_dynamic_define.h" @@ -47,14 +48,13 @@ int PCRESetup(struct _SnortConfig *sc, Rule *rule, PCREInfo *pcreInfo) { - const char *error; - int erroffset; + int error; + PCRE2_SIZE erroffset; pcreInfo->compiled_expr = (void *)_ded.pcreCompile(pcreInfo->expr, pcreInfo->compile_flags, &error, - &erroffset, - NULL); + &erroffset); if (!pcreInfo->compiled_expr) { @@ -65,18 +65,17 @@ } else { - pcreInfo->compiled_extra = (void *)_ded.pcreStudy(sc, pcreInfo->compiled_expr, pcreInfo->compile_flags, &error); + pcreInfo->ctxt = (void *)_ded.pcreStudy(sc, pcreInfo->compile_flags); } - if (error) + if (!pcreInfo->ctxt) { - /* error doing study. */ - _ded.errMsg("Failed to study PCRE in dynamic rule [%d:%d]\n", + _ded.errMsg("Failed to create PCRE context in dynamic rule [%d:%d]\n", rule->info.genID, rule->info.sigID); return -1; } - _ded.pcreCapture(sc, pcreInfo->compiled_expr, pcreInfo->compiled_extra); + _ded.pcreCapture(sc, pcreInfo->compiled_expr); return 0; @@ -86,7 +85,7 @@ * * Wrapper for pcre_exec to expose ovector. * */ ENGINE_LINKAGE int pcreExecWrapper(const PCREInfo *pcre_info, const char *buf, int len, int start_offset, - int options, int *ovector, int ovecsize) + int options, PCRE2_SIZE *ovector, int ovecsize) { int result; int matched; @@ -95,14 +94,13 @@ || buf == NULL || len <= 0 || start_offset < 0 - || start_offset >= len - || ovector == NULL) + || start_offset >= len) { return 0; } result = _ded.pcreExec(pcre_info->compiled_expr, /* result of pcre_compile() */ - pcre_info->compiled_extra, /* result of pcre_study() */ + pcre_info->ctxt, /* match context */ buf, /* the subject string */ len, /* the length of the subject string */ start_offset, /* start at offset 0 in the subject */ @@ -114,13 +112,13 @@ { matched = 1; } - else if(result == PCRE_ERROR_NOMATCH) + else if(result == PCRE2_ERROR_NOMATCH) { matched = 0; } else { - DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre_exec error : %d \n", result);); + DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre2_match error : %d \n", result);); return 0; } @@ -157,7 +155,7 @@ int matched; int result; - int *ovector; + PCRE2_SIZE *ovector; int ovector_size; _ded.pcreOvectorInfo(&ovector, &ovector_size); @@ -177,7 +175,7 @@ *found_offset = -1; result = _ded.pcreExec(pcre_info->compiled_expr,/* result of pcre_compile() */ - pcre_info->compiled_extra, /* result of pcre_study() */ + pcre_info->ctxt, /* match context */ buf, /* the subject string */ len, /* the length of the subject string */ start_offset, /* start at offset 0 in the subject */ @@ -189,7 +187,7 @@ { matched = 1; } - else if(result == PCRE_ERROR_NOMATCH) + else if(result == PCRE2_ERROR_NOMATCH) { matched = 0; } @@ -201,7 +199,7 @@ if (found_offset) { - *found_offset = ovector[1]; + *found_offset = (int)ovector[1]; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Setting buffer and found_offset: %p %d\n", buf, found_offset);); --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_dynamic_engine.h +++ snort-2.9.15.1/src/dynamic-plugins/sf_dynamic_engine.h @@ -139,11 +139,11 @@ #define ENGINE_DATA_VERSION 10 -typedef void *(*PCRECompileFunc)(const char *, int, const char **, int *, const unsigned char *); -typedef void *(*PCREStudyFunc)(struct _SnortConfig *, const void *, int, const char **); -typedef int (*PCREExecFunc)(const void *, const void *, const char *, int, int, int, int *, int); -typedef void (*PCRECapture)(struct _SnortConfig *, const void *, const void *); -typedef void(*PCREOvectorInfo)(int **, int *); +typedef void *(*PCRECompileFunc)(const char *, uint32_t, int *, size_t *); +typedef void *(*PCREStudyFunc)(struct _SnortConfig *, int); +typedef int (*PCREExecFunc)(const void *, const void *, const char *, int, int, int, size_t *, int); +typedef void (*PCRECapture)(struct _SnortConfig *, const void *); +typedef void(*PCREOvectorInfo)(size_t **, int *); typedef struct _DynamicEngineData { --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_dynamic_plugins.c +++ snort-2.9.15.1/src/dynamic-plugins/sf_dynamic_plugins.c @@ -90,7 +90,8 @@ #include "sf_iph.h" #include "fpdetect.h" #include "sfportobject.h" -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "parser.h" #include "event_wrapper.h" #include "util.h" @@ -1243,88 +1244,50 @@ } } -void *pcreCompile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr) +void *pcreCompile(const char *pattern, uint32_t options, int *errptr, PCRE2_SIZE *erroffset) { options &= ~SNORT_PCRE_OVERRIDE_MATCH_LIMIT; - return (void *)pcre_compile(pattern, options, errptr, erroffset, tableptr); + return (void *)pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, options, errptr, erroffset, NULL); } -void *pcreStudy(struct _SnortConfig *sc, const void *code, int options, const char **errptr) +void *pcreStudy(struct _SnortConfig *sc, int options) { - pcre_extra *extra_extra; + pcre2_match_context *ctxt; int snort_options = options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT; - extra_extra = pcre_study((const pcre*)code, 0, errptr); - - if (extra_extra) - { - if ((ScPcreMatchLimitNewConf(sc) != -1) && !(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT)) - { - if (extra_extra->flags & PCRE_EXTRA_MATCH_LIMIT) - { - extra_extra->match_limit = ScPcreMatchLimitNewConf(sc); - } - else - { - extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT; - extra_extra->match_limit = ScPcreMatchLimitNewConf(sc); - } - } + if (!(ctxt = pcre2_match_context_create(NULL))) + return NULL; -#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION - if ((ScPcreMatchLimitRecursionNewConf(sc) != -1) && !(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT)) - { - if (extra_extra->flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) - { - extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc); - } - else - { - extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; - extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc); - } - } -#endif - } - else - { - if (!(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT) && - ((ScPcreMatchLimitNewConf(sc) != -1) || (ScPcreMatchLimitRecursionNewConf(sc) != -1))) - { - extra_extra = (pcre_extra *)SnortAlloc(sizeof(pcre_extra)); - if (ScPcreMatchLimitNewConf(sc) != -1) - { - extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT; - extra_extra->match_limit = ScPcreMatchLimitNewConf(sc); - } + if ((ScPcreMatchLimitNewConf(sc) != -1) && !(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT)) + pcre2_set_match_limit(ctxt, ScPcreMatchLimitNewConf(sc)); -#ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION - if (ScPcreMatchLimitRecursionNewConf(sc) != -1) - { - extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; - extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc); - } -#endif - } - } + if ((ScPcreMatchLimitRecursionNewConf(sc) != -1) && !(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT)) + pcre2_set_depth_limit(ctxt, ScPcreMatchLimitRecursionNewConf(sc)); - return extra_extra; + return ctxt; } /* pcreOvectorInfo * * Get the Ovector configuration for PCRE from the snort.conf */ -void pcreOvectorInfo(int **ovector, int *ovector_size) +void pcreOvectorInfo(PCRE2_SIZE **ovector, int *ovector_size) { *ovector = snort_conf->pcre_ovector; *ovector_size = snort_conf->pcre_ovector_size; } int pcreExec(const void *code, const void *extra, const char *subj, - int len, int start, int options, int *ovec, int ovecsize) + int len, int start, int options, PCRE2_SIZE *ovec, int ovecsize) { - return pcre_exec((const pcre *)code, (const pcre_extra *)extra, subj, len, start, options, ovec, ovecsize); + pcre2_match_data *md; + int rc; + + md = pcre2_match_data_create(ovecsize, NULL); + rc = pcre2_match((pcre2_code *)code, (PCRE2_SPTR)subj, len, start, options, md, (pcre2_match_context *)extra); + ovec = pcre2_get_ovector_pointer(md); + pcre2_match_data_free(md); + return rc; } static int setFlowId(const void* p, uint32_t id) --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_convert_dynamic.c +++ snort-2.9.15.1/src/dynamic-plugins/sf_convert_dynamic.c @@ -52,9 +52,9 @@ extern void ParsePattern(char *, OptTreeNode *, int); extern void ParseProtectedPattern(char *, OptTreeNode *, int); -extern void *pcreCompile(const char *pattern, int options, const char **errptr, - int *erroffset, const unsigned char *tableptr); -extern void *pcreStudy(struct _SnortConfig *sc, const void *code, int options, const char **errptr); +extern void *pcreCompile(const char *pattern, uint32_t options, int *errptr, + PCRE2_SIZE *erroffset); +extern void *pcreStudy(struct _SnortConfig *sc, int options); extern int SnortPcre(void *option_data, Packet *p); extern int FlowBitsCheck(void *option_data, Packet *p); @@ -520,8 +520,8 @@ PCREInfo *pcre_info = rule->options[index]->option_u.pcre; OptFpList *fpl; void *pcre_dup; - const char *error; - int erroroffset; + int error; + PCRE2_SIZE erroroffset; /* Need to recompile the expression so double free doesn't occur * during reload */ @@ -531,8 +531,7 @@ pcre_info->expr, pcre_info->compile_flags, &error, - &erroroffset, - NULL + &erroroffset ); if (pcre_data->re == NULL) @@ -541,15 +540,13 @@ return -1; } - pcre_data->pe = pcreStudy(sc, - pcre_data->re, - pcre_info->compile_flags, - &error + pcre_data->ctxt = pcreStudy(sc, + pcre_info->compile_flags ); - if (error) + if (!pcre_data->ctxt) { - free(pcre_data->re); + pcre2_code_free(pcre_data->re); free(pcre_data); return -1; } @@ -584,10 +581,10 @@ { if (pcre_data->expression) free(pcre_data->expression); - if (pcre_data->pe) - free(pcre_data->pe); + if (pcre_data->ctxt) + pcre2_match_context_free(pcre_data->ctxt); if (pcre_data->re) - free(pcre_data->re); + pcre2_code_free(pcre_data->re); free(pcre_data); pcre_data = pcre_dup; --- snort-2.9.15.1.orig/src/dynamic-preprocessors/pop/snort_pop.h +++ snort-2.9.15.1/src/dynamic-preprocessors/pop/snort_pop.h @@ -38,7 +38,8 @@ /* Includes ***************************************************************/ -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "sf_snort_packet.h" #include "pop_config.h" --- snort-2.9.15.1.orig/src/dynamic-preprocessors/imap/snort_imap.h +++ snort-2.9.15.1/src/dynamic-preprocessors/imap/snort_imap.h @@ -38,7 +38,8 @@ /* Includes ***************************************************************/ -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "sf_snort_packet.h" #include "imap_config.h" @@ -216,8 +217,7 @@ typedef struct _IMAPPcre { - pcre *re; - pcre_extra *pe; + pcre2_code *re; } IMAPPcre; --- snort-2.9.15.1.orig/src/dynamic-preprocessors/smtp/snort_smtp.h +++ snort-2.9.15.1/src/dynamic-preprocessors/smtp/snort_smtp.h @@ -39,7 +39,8 @@ /* Includes ***************************************************************/ -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "sf_snort_packet.h" #include "ssl.h" --- snort-2.9.15.1.orig/src/dynamic-preprocessors/appid/luaDetectorApi.c +++ snort-2.9.15.1/src/dynamic-preprocessors/appid/luaDetectorApi.c @@ -38,7 +38,8 @@ #include "luaDetectorModule.h" #include "luaDetectorApi.h" #include "luaDetectorFlowApi.h" -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "httpCommon.h" #include "sf_multi_mpse.h" #include "fw_appid.h" @@ -1366,10 +1367,12 @@ Detector *detector; char *pattern; unsigned int offset; - pcre *re; - int ovector[OVECCOUNT]; - const char *error; - int erroffset; + pcre2_code *re; + pcre2_match_data *md; + PCRE2_SIZE *ovector; + PCRE2_UCHAR error[120]; + PCRE2_SIZE erroffset; + int err; int rc, i; DetectorUserData *detectorUserData = checkDetectorUserData(L, 1); @@ -1385,43 +1388,46 @@ { /*compile the regular expression pattern, and handle errors */ - re = pcre_compile( - pattern, /*the pattern */ - PCRE_DOTALL, /*default options - dot matches everything including newline */ - &error, /*for error message */ + re = pcre2_compile( + (PCRE2_SPTR)pattern, /*the pattern */ + PCRE2_ZERO_TERMINATED, + PCRE2_DOTALL, /*default options - dot matches everything including newline */ + &err, /*for error code */ &erroffset, /*for error offset */ - NULL); /*use default character tables */ + NULL); /*compile context */ if (re == NULL) { - _dpd.errMsg("PCRE compilation failed at offset %d: %s\n",erroffset, error); + pcre2_get_error_message(err, error, sizeof(error)); + _dpd.errMsg("PCRE compilation failed at offset %zu: %s\n",erroffset, error); return 0; } /*pattern match against the subject string. */ - rc = pcre_exec( + md = pcre2_match_data_create(OVECCOUNT, NULL); + rc = pcre2_match( re, /*compiled pattern */ - NULL, /*no extra data */ - (char *)detector->validateParams.data, /*subject string */ + detector->validateParams.data, /*subject string */ detector->validateParams.size, /*length of the subject */ offset, /*offset 0 */ 0, /*default options */ - ovector, /*output vector for substring information */ - OVECCOUNT); /*number of elements in the output vector */ + md, /*match data */ + NULL); /*match context */ if (rc < 0) { /*Matching failed: clubbing PCRE_ERROR_NOMATCH with other errors. */ - pcre_free(re); + pcre2_code_free(re); + pcre2_match_data_free(md); return 0; } /*Match succeded */ /*printf("\nMatch succeeded at offset %d", ovector[0]); */ - pcre_free(re); + pcre2_code_free(re); if (rc == 0) @@ -1436,11 +1442,13 @@ lua_checkstack (L, rc); + ovector = pcre2_get_ovector_pointer(md); for (i = 0; i < rc; i++) { /*printf("%2d: %.*s\n", i, , substring_start); */ - lua_pushlstring(L, (char *)detector->validateParams.data + ovector[2*i], ovector[2*i+1] - ovector[2*i]); + lua_pushlstring(L, (char *)detector->validateParams.data + (int)ovector[2*i], (int)(ovector[2*i+1] - ovector[2*i])); } + pcre2_match_data_free(md); return rc; } --- snort-2.9.15.1.orig/src/util.c +++ snort-2.9.15.1/src/util.c @@ -78,7 +78,8 @@ #include "plugbase.h" #include "sf_types.h" #include "sflsq.h" -#include "pcre.h" +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "mpse.h" #include "ppm.h" #include "active.h" @@ -174,7 +175,7 @@ int DisplayBanner(void) { const char * info; - const char * pcre_ver; + char pcre_ver[24]; const char * zlib_ver; info = getenv("HOSTTYPE"); @@ -183,7 +184,7 @@ info=""; } - pcre_ver = pcre_version(); + pcre2_config(PCRE2_CONFIG_VERSION, pcre_ver); zlib_ver = zlib_version; LogMessage("\n"); --- snort-2.9.15.1.orig/src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c +++ snort-2.9.15.1/src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c @@ -1124,14 +1124,14 @@ if (pcre->compiled_expr != NULL) { - free(pcre->compiled_expr); + pcre2_code_free((pcre2_code *)pcre->compiled_expr); pcre->compiled_expr = NULL; } - if (pcre->compiled_extra != NULL) + if (pcre->ctxt != NULL) { - free(pcre->compiled_extra); - pcre->compiled_extra = NULL; + pcre2_match_context_free((pcre2_match_context *)pcre->ctxt); + pcre->ctxt = NULL; } } --- snort-2.9.15.1.orig/src/snort.c +++ snort-2.9.15.1/src/snort.c @@ -4308,9 +4308,6 @@ OtnxMatchDataFree(sc->omd); - if (sc->pcre_ovector != NULL) - free(sc->pcre_ovector); - if ( sc->event_queue_config ) EventQueueConfigFree(sc->event_queue_config); --- snort-2.9.15.1.orig/src/snort.h +++ snort-2.9.15.1/src/snort.h @@ -815,7 +815,7 @@ long int tagged_packet_limit; /* config tagged_packet_limit */ long int pcre_match_limit; /* config pcre_match_limit */ long int pcre_match_limit_recursion; /* config pcre_match_limit_recursion */ - int *pcre_ovector; + size_t *pcre_ovector; int pcre_ovector_size; #ifdef PERF_PROFILING