Skip to content

fix: add msc_fullinfo() to check JIT compilation #3375

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 10, 2025

Conversation

airween
Copy link
Member

@airween airween commented May 10, 2025

what

I usually use mod_security2 Apache module with these build options:

./configure --enable-pcre-study=yes --enable-pcre-jit=yes --with-pcre2

During an issue investigation I ran into an interesting message. Consider this rule:

SecRule ARGS "@verifyCC \d{13,16}" "id:1,phase:2,log,capture,pass"

and this payload:

$ cat jsonpayload.json
[1234567890123456,1234567890123456,1234567890123456]

When I send this request:

curl -H "Content-Type: application/json" -X POST -d @jsonpayload.json http://localhost

I see these messages in debug.log:

Rule 7fbd7d71a6d0 [id "1"][file "test.conf"][line "476"] - Execution error - Does not support JIT (0).

Which is not true.

why

The problem is that the regex engine (in case of using PCRE2) does not handle the jit variable correctly (in case of verifyCC operator this variable is here, as you can see it's initialized with 0).

Let's see what happens when the engine runs any of the relevant codes (and user used the same build options).

The engine has its own regex structure which has a member with name jit_compile_rc. This stores the information about the engine is able to use JIT or not.

When a rule use the PCRE engine, it fills the regex object and set jit_compile_rc member here.

#ifdef WITH_PCRE_JIT
    regex->jit_compile_rc = pcre2_jit_compile(regex->re, PCRE2_JIT_COMPLETE);
#endif

As I wrote above, at the operator the jit variable is initialized with 0, and in case of PCRE2 it does not change during the execution.

The condition is here:

        if ((rc != 0) || (jit != 1)) {
            *error_msg = apr_psprintf(msr->mp,
                    "Rule %pp [id \"%s\"][file \"%s\"][line \"%d\"] - "
                    "Execution error - "
                    ... other part of error message...
        }

The variable rc is set here:

            #ifdef WITH_PCRE2
        rc = regex->jit_compile_rc;
            #else

so the rc will hold the value of pcre2_jit_compile()'s return value. Let's see what is the return value of this function:

"Such a call returns zero if JIT is available and has a working allocator"

So the variable rc will be 0 (if JIT is available). But what about the variable jit? It's still 0. As you can see in case of old PCRE code, it calls msc_fullinfo(), which in case of PCRE2 decides JIT is usable or not with calling the function pcre2_pattern_info(). See how does it work:

"A non-zero result means that JIT compilation was successful. A result of 0 means that JIT support is not available, or the pattern was not processed by pcre2_jit_compile()"

This is necessary to get a full description of JIT status in current call, and sets the correct value of jit.

@airween airween requested review from theseion and fzipi May 10, 2025 08:58
Copy link
Collaborator

@theseion theseion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

theseion
theseion previously approved these changes May 10, 2025
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
25.0% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@airween airween requested a review from theseion May 10, 2025 11:23
@airween airween merged commit e0e732a into owasp-modsecurity:v2/master May 10, 2025
41 of 42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants