acd: seed bestPerm to avoid an uninitialised read in enumerate_iset_combinations

bestPerm is only written inside the 'cost < best_cost' branch. When no
combination beats the initial best_cost -- which happens for an infeasible
free-set size -- the array is never written, yet the tail of the function still
evaluates permutations[bestPerm[i]]. That reads uninitialised stack and then
uses the value to index permutations[], so it is an out-of-bounds read as well.

Upstream results are unaffected in practice because the caller discards the
permutation on that path, but it is undefined behaviour and it becomes a hard
segfault as soon as the stack layout changes -- adding two members to the
decomposer object was enough to trigger it reliably.

Seeding the identity permutation in the existing initialisation loop is
sufficient and costs nothing.
This commit is contained in:
Marcel Walter 2026-08-08 08:43:10 +02:00
parent 8e224cd794
commit 4473e39efc
No known key found for this signature in database
GPG Key ID: 2979DB71A0C2C23D
1 changed files with 5 additions and 0 deletions

View File

@ -482,6 +482,11 @@ private:
for ( uint32_t i = 0; i < num_vars; ++i )
{
pComb[i] = pInvPerm[i] = i;
/* bestPerm is written only when some combination beats the initial
* best_cost. When none does, the loop below still evaluates
* permutations[bestPerm[i]], which reads uninitialised stack and then
* indexes permutations[] with it. Seed the identity permutation. */
bestPerm[i] = i;
}
/* early bail-out conditions */