Ocaml: Str partial-match stale capture registers underflow
Affects ocamlSource GCVE Database
Public exploit available · CVSS 7.0 High · fixed in feccd4744ebe25b90208e569d03efd514b964dce : patch ocaml as a priority.
Data as of 26 Oct 2026, 16:14 UTC
- Patch
- Available – fixed in feccd4744ebe25b90208e569d03efd514b964dce, 824dadcbde77aea27d84b8d70a72442b8fcb344a, 5.5.2
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:H/SC:N/SI:N/SA:N/E:P/AU:Y/R:UWhat to do
Upgrade ocaml to feccd4744ebe25b90208e569d03efd514b964dce, 824dadcbde77aea27d84b8d70a72442b8fcb344a or 5.5.2.
Affected software
| Product | Affected | Fixed in |
|---|---|---|
opamocamlpkg:opam/ocamlOther threats | Affected
| Fixed in
|
Check your own hosts for these packages with threat-finder (opens in a new tab), our free open-source scanner.
Description
ANT-2026-KKC4QS4S Str partial-match stale capture registers underflow `Str.string_partial_match` records the beginning and end of a captured group. There was an implicit assumption that `beginning <= end`. However if it reached the end of the matched string but not the end of the regexp, it was possible for the beginning of the group to be matched at iteration N of the star operator, and the end of the group to be matched at iteration N-1, resulting in `beginning > end`. `Str.matched_group` is safe, it fails with an `Invalid_argument` on groups with `beginning > end`, but `Str.replace_matched` can crash, trying to memcpy `end - beginning` bytes. The example in the ANT is `ab` partially matched against `\(\(a\)b\)+`. Group 2 has `beginning = 2` and `end = 1`. ## Fix The fix is to record groups with `beginning > end` as not matched. ## Am I affected? All of the following conditions are necessary: * you need to use `Str.string_partial_match` * if you don't use this function you are not affected * you need to use one of `Str.{replace_matched,global_replace,replace_first}` on the same regexp after a call to `Str.string_partial_match`. * If you use `Str.group_beginning` and `Str.group_end` and do your own string manipulation that is safe, because the String module would raise on out of bounds accesses. Similarly `Str.matched_group` is safe (uses `String` functions in its OCaml implementation) * the match replacement must reference a group > 0 * if the replacement string argument is fixed, and doesn't reference any groups, or references only group 0, then you are not affected * the referenced replacement group must be under a repetition operator in the original regexp * if there is no repetition operator in the regexp, or there are no groups under the repetition operator then you are not affected For example `{|\(\(a\)b\)+|}` as the regular expression in a call to `Str.string_partial_match`, followed by a reference to `\2` in the argument of `Str.replace_matched` could be affected. ## Timeline - 2026-08-24: vulnerability was found - 2026-08-27: forwarded report to security@ocaml.org - 2026-09-29: fix merged to trunk