Skip to content

Heap out-of-bounds read in byte-mode approximate regex matching #143

Description

@fa1c4

Summary

TRE's approximate regex matching path can read past the end of a small heap allocation when processing a short byte-mode regular expression and text input. A crafted pattern/text pair reaches the approximate matcher through tre_regncompb() and tre_regaexecb(), then triggers a heap-buffer-overflow read under AddressSanitizer.

Affected version

  • Repository: laurikari/tre
  • Tested commit: 71bfcaf0af3994384987c6c2679ed7d078ffe189
  • Affected component: TRE approximate matching
  • Relevant code paths: tre_regaexecb(), tre_match_approx(), and tre_tnfa_run_approx()

Earlier versions containing the same approximate matching implementation may also be affected.

Root cause

The crash occurs in the approximate matching engine when a very small byte-mode input reaches internal state/tag handling. The fuzz case reads four bytes just past a four-byte allocation. The likely root cause is missing bounds validation in the approximate matcher for small inputs and/or small state/tag arrays.

The relevant execution path is:

tre_regncompb()  // compile byte-mode regex
tre_regaexecb()  // execute approximate byte-mode matching
tre_match_approx()
tre_tnfa_run_approx()

Minimal trigger

The PoC constructs the pattern and text from this byte sequence:

0a 41 7e 7e 7e 5b 7a 08

It uses:

std::string pattern(reinterpret_cast<const char *>(input) + 5, 1);
std::string text(reinterpret_cast<const char *>(input) + 6, input_len - 6);

and executes approximate matching with:

params.max_cost = 7;
params.max_ins = 4;
params.max_del = 4;
params.max_subst = 1;
params.max_err = 9;
tre_regaexecb(&preg, text.c_str(), &match, params, 0);

Impact

Applications that use TRE approximate matching on untrusted regular expressions or untrusted text can be crashed by a crafted input. Depending on allocator layout and embedding application behavior, the out-of-bounds read may also expose adjacent heap data to internal matching logic, but the confirmed impact is denial of service.

Expected behavior

The approximate matcher should reject invalid states or return a normal no-match/error result. It should not read outside heap allocations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions