CVE-2026-72703
MediumCVSS 6.3Exploitation Probability (EPSS)
Low risk2th percentile - higher than 2% of all known CVEs
Summary
The guard checker in Rocq Prover treats a parameter of a nested mutual fixpoint as uniform without examining calls between the different bodies of that fixpoint. find_uniform_parameters in kernel/inductive.ml inspects only self-recursive calls, so when no body calls itself the function concludes that every parameter is uniform. A parameter that grows through a cross-call from one body to another keeps the subterm specification it inherited from the enclosing fixpoint, allowing a recursive call that is not structurally smaller to be accepted. This leads to a non-terminating definition and a proof of False. Introduced in Coq 8.20 and fixed in Rocq 9.2.0.
Risk Assessment
The risk includes the possibility of proving false statements in the system, which could undermine the security of formal proofs.
Recommendation
Upgrade Rocq Prover to version 9.2.0 or later.
Other vulnerabilities in Rocq Prover
See all- CVE-2026-72714Medium
Rocq Prover does not restore the universe graph's copy of the universe checking flag when a module that locally disabled the check is closed. This causes a disagreement between views: Test Universe Checking reports the check as enabled while the kernel continues to accept universe-inconsistent terms. This allows Hurkens' paradox to be applied, yielding a proof of False. No fix is available.
- CVE-2026-72705Medium
The guard checker in Rocq Prover does not follow recursive calls made through a fixpoint's own arguments. A fixpoint may pass itself as a higher-order argument to a second fixpoint, which then applies it to a value that is not a subterm of the structural argument. This admits a type that is definitionally equal to its own negation, so self-application produces False. Fixed in Rocq 9.2.0.
- CVE-2026-72704Medium
The guard checker in Rocq Prover does not recheck the recursive tree representation of an inductive type parameter after that parameter has been changed by transport. A fixpoint may apply a rewrite along an equality between types to its recursive argument, which is accepted but alters the recursive tree. A second fixpoint inherits the altered tree without verification, allowing a non-structurally decreasing call to be accepted. This leads to a non-terminating definition and a proof of False. A fix is proposed but not merged.
Original NVD description (English source)
The guard checker in Rocq Prover treats a parameter of a nested mutual fixpoint as uniform without examining calls between the different bodies of that fixpoint. find_uniform_parameters in kernel/inductive.ml inspects only self-recursive calls, so when no body calls itself the function concludes that every parameter is uniform. A parameter that grows through a cross-call from one body to another therefore keeps the subterm specification it inherited from the enclosing fixpoint, and a recursive call guarded by that specification is accepted although the argument is not structurally smaller. A non-terminating definition is admitted as structurally decreasing, which yields a term whose value equals its own successor and so a proof of False, from which any proposition follows. The proof requires no axioms, plugins or unsafe flags and Print Assumptions reports it as closed under the global context. Introduced in Coq 8.20 and fixed in Rocq 9.2.0.

