diff --git a/CHANGES b/CHANGES index 15d4f2b385..23d1e4f917 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ DD mmm YYYY - 2.9.x (to be released) ------------------- + * Support for JIT option for PCRE2 + [Issue #2840 - @martinhsv] * Use uid for user if apr_uid_name_get() fails [Issue #2046 - @arminabf, @marcstern] * Fix: handle error with SecConnReadStateLimit configuration diff --git a/apache2/msc_pcre.c b/apache2/msc_pcre.c index ef9aa0f894..e2ce2a4f0e 100644 --- a/apache2/msc_pcre.c +++ b/apache2/msc_pcre.c @@ -84,7 +84,9 @@ void *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options, return NULL; } - /* TODO: Add PCRE2 JIT support */ +#ifdef WITH_PCRE_JIT + regex->jit_compile_rc = pcre2_jit_compile(regex->re, PCRE2_JIT_COMPLETE); +#endif /* Setup the pcre2 match context */ regex->match_context = NULL; @@ -242,27 +244,38 @@ int msc_regexec_ex(msc_regex_t *regex, const char *s, unsigned int slen, PCRE2_SPTR pcre2_s; int pcre2_ret; pcre2_match_data *match_data; - PCRE2_SIZE *pcre2_ovector = NULL; + PCRE2_SIZE *pcre2_ovector = NULL; pcre2_s = (PCRE2_SPTR)s; match_data = pcre2_match_data_create_from_pattern(regex->re, NULL); - pcre2_ret = pcre2_match(regex->re, pcre2_s, (PCRE2_SIZE)strlen(s), +#ifdef WITH_PCRE_JIT + if (regex->jit_compile_rc == 0) { + pcre2_ret = pcre2_jit_match(regex->re, pcre2_s, (PCRE2_SIZE)strlen(s), + (PCRE2_SIZE)(startoffset), (uint32_t)options, match_data, regex->match_context); + } + if (regex->jit_compile_rc != 0 || pcre2_ret == PCRE2_ERROR_JIT_STACKLIMIT) { + pcre2_ret = pcre2_match(regex->re, pcre2_s, (PCRE2_SIZE)strlen(s), + (PCRE2_SIZE)(startoffset), (PCRE2_NO_JIT | (uint32_t)options), match_data, regex->match_context); + } +#else + pcre2_ret = pcre2_match(regex->re, pcre2_s, (PCRE2_SIZE)strlen(s), (PCRE2_SIZE)(startoffset), (uint32_t)options, match_data, regex->match_context); - if (match_data != NULL) { - if (ovector != NULL) { - pcre2_ovector = pcre2_get_ovector_pointer(match_data); - if (pcre2_ovector != NULL) { +#endif + if (match_data != NULL) { + if (ovector != NULL) { + pcre2_ovector = pcre2_get_ovector_pointer(match_data); + if (pcre2_ovector != NULL) { for (int i = 0; ((i < pcre2_ret) && ((i*2) <= ovecsize)); i++) { if ((i*2) < ovecsize) { ovector[2*i] = pcre2_ovector[2*i]; ovector[2*i+1] = pcre2_ovector[2*i+1]; } - } - } - } + } + } + } pcre2_match_data_free(match_data); - } + } if ((pcre2_ret*2) > ovecsize) { return 0; } else { diff --git a/apache2/msc_pcre.h b/apache2/msc_pcre.h index 4871c1f8fa..c0ab37b4ae 100644 --- a/apache2/msc_pcre.h +++ b/apache2/msc_pcre.h @@ -45,6 +45,10 @@ struct msc_regex_t { #ifdef WITH_PCRE2 pcre2_code *re; pcre2_match_context *match_context; +#ifdef WITH_PCRE_JIT + int jit_compile_rc; +#endif + #else void *re; void *pe; diff --git a/apache2/re_operators.c b/apache2/re_operators.c index 9217ad7923..e68aa9cd2a 100644 --- a/apache2/re_operators.c +++ b/apache2/re_operators.c @@ -711,7 +711,11 @@ static int msre_op_validateHash_param_init(msre_rule *rule, char **error_msg) { #ifdef WITH_PCRE_STUDY #ifdef WITH_PCRE_JIT + #ifdef WITH_PCRE2 + rc = regex->jit_compile_rc; + #else rc = msc_fullinfo(regex, PCRE_INFO_JIT, &jit); + #endif if ((rc != 0) || (jit != 1)) { *error_msg = apr_psprintf(rule->ruleset->mp, "Rule %pp [id \"%s\"][file \"%s\"][line \"%d\"] - " @@ -808,7 +812,11 @@ static int msre_op_validateHash_execute(modsec_rec *msr, msre_rule *rule, msre_v #ifdef WITH_PCRE_STUDY #ifdef WITH_PCRE_JIT if (msr->txcfg->debuglog_level >= 4) { + #ifdef WITH_PCRE2 + rc = regex->jit_compile_rc; + #else rc = msc_fullinfo(regex, PCRE_INFO_JIT, &jit); + #endif if ((rc != 0) || (jit != 1)) { *error_msg = apr_psprintf(msr->mp, "Rule %pp [id \"%s\"][file \"%s\"][line \"%d\"] - " @@ -973,7 +981,11 @@ static int msre_op_rx_param_init(msre_rule *rule, char **error_msg) { #ifdef WITH_PCRE_STUDY #ifdef WITH_PCRE_JIT + #ifdef WITH_PCRE2 + rc = regex->jit_compile_rc; + #else rc = msc_fullinfo(regex, PCRE_INFO_JIT, &jit); + #endif if ((rc != 0) || (jit != 1)) { *error_msg = apr_psprintf(rule->ruleset->mp, "Rule %pp [id \"%s\"][file \"%s\"][line \"%d\"] - " @@ -1060,7 +1072,11 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c #ifdef WITH_PCRE_STUDY #ifdef WITH_PCRE_JIT if (msr->txcfg->debuglog_level >= 4) { + #ifdef WITH_PCRE2 + rc = regex->jit_compile_rc; + #else rc = msc_fullinfo(regex, PCRE_INFO_JIT, &jit); + #endif if ((rc != 0) || (jit != 1)) { *error_msg = apr_psprintf(msr->mp, "Rule %pp [id \"%s\"][file \"%s\"][line \"%d\"] - " @@ -2842,7 +2858,11 @@ static int msre_op_verifyCC_execute(modsec_rec *msr, msre_rule *rule, msre_var * #ifdef WITH_PCRE_STUDY #ifdef WITH_PCRE_JIT if (msr->txcfg->debuglog_level >= 4) { + #ifdef WITH_PCRE2 + rc = regex->jit_compile_rc; + #else rc = msc_fullinfo(regex, PCRE_INFO_JIT, &jit); + #endif if ((rc != 0) || (jit != 1)) { *error_msg = apr_psprintf(msr->mp, "Rule %pp [id \"%s\"][file \"%s\"][line \"%d\"] - " @@ -3169,7 +3189,11 @@ static int msre_op_verifyCPF_execute(modsec_rec *msr, msre_rule *rule, msre_var #ifdef WITH_PCRE_STUDY #ifdef WITH_PCRE_JIT if (msr->txcfg->debuglog_level >= 4) { + #ifdef WITH_PCRE2 + rc = regex->jit_compile_rc; + #else rc = msc_fullinfo(regex, PCRE_INFO_JIT, &jit); + #endif if ((rc != 0) || (jit != 1)) { *error_msg = apr_psprintf(msr->mp, "Rule %pp [id \"%s\"][file \"%s\"][line \"%d\"] - " @@ -3479,7 +3503,11 @@ static int msre_op_verifySSN_execute(modsec_rec *msr, msre_rule *rule, msre_var #ifdef WITH_PCRE_STUDY #ifdef WITH_PCRE_JIT if (msr->txcfg->debuglog_level >= 4) { + #ifdef WITH_PCRE2 + rc = regex->jit_compile_rc; + #else rc = msc_fullinfo(regex, PCRE_INFO_JIT, &jit); + #endif if ((rc != 0) || (jit != 1)) { *error_msg = apr_psprintf(msr->mp, "Rule %pp [id \"%s\"][file \"%s\"][line \"%d\"] - "