CVE-2026-72704
MediumCVSS 6.3Exploitation Probability (EPSS)
Low risk2th percentile - higher than 2% of all known CVEs
Summary
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.
Risk Assessment
The risk includes the possibility of proving false statements in the system, which could undermine the security of formal proofs.
Recommendation
Monitor the status of the fix and avoid using transport in recursive definitions until it is implemented.
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-72703Medium
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.
Original NVD description (English source)
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 the guard checker accepts because the inductive type is preserved, while the recursive tree recorded for the parameter is altered. A second fixpoint that calls the first inherits the altered recursive tree without verification, so a call that is not structurally decreasing is accepted as terminating. The resulting non-terminating definition proves that a natural number equals its own successor and therefore False, from which any proposition follows. The demonstration uses two axioms that follow from univalence and are consistent with the calculus of inductive constructions, so the contradiction comes from the guard check rather than from the assumptions. A fix is proposed but not merged.

