Fix use-after-free with unsat cores/proofs (#174)
authorAndres Nötzli <andres.noetzli@gmail.com>
Fri, 30 Jun 2017 18:39:17 +0000 (11:39 -0700)
committerGitHub <noreply@github.com>
Fri, 30 Jun 2017 18:39:17 +0000 (11:39 -0700)
In TSatProof<Solver>::finalizeProof(), we got a clause from the clause
allocator, called resolveUnit() and then size() on the clause. The problem is
that resolveUnit() can reallocate memory (and there is even a comment warning
about that in finalizeProof()), which invalidates the clause. This commit gets
the clause again from the clause allocator before calling size().

src/proof/sat_proof_implementation.h

index 6cb10450acba87ef6e99c94797e5daed02100e41..44d98e88e9248e7e720bb941e6e7677367a8a3f8 100644 (file)
@@ -903,13 +903,11 @@ void TSatProof<Solver>::finalizeProof(typename Solver::TCRef conflict_ref) {
   ResChain<Solver>* res = new ResChain<Solver>(conflict_id);
   // Here, the call to resolveUnit() can reallocate memory in the
   // clause allocator.  So reload conflict ptr each time.
-  size_t conflict_size = getClause(conflict_ref).size();
-  for (size_t i = 0; i < conflict_size; ++i) {
+  for (size_t i = 0; i < getClause(conflict_ref).size(); ++i) {
     const typename Solver::TClause& conflict = getClause(conflict_ref);
     typename Solver::TLit lit = conflict[i];
     ClauseId res_id = resolveUnit(~lit);
     res->addStep(lit, res_id, !sign(lit));
-    conflict_size = conflict.size();
   }
 
   registerResolution(d_emptyClauseId, res);