Skip to content

test(bb): fix out-of-bounds read in acir_components_check DetectsUnconstrainedWitnesses#24703

Draft
AztecBot wants to merge 1 commit into
nextfrom
cb/81fe526b5463
Draft

test(bb): fix out-of-bounds read in acir_components_check DetectsUnconstrainedWitnesses#24703
AztecBot wants to merge 1 commit into
nextfrom
cb/81fe526b5463

Conversation

@AztecBot

Copy link
Copy Markdown
Collaborator

Problem

The Nightly Debug Build failed (exit 134 / SIGABRT). The failing test is AcirComponentsCheckTest.DetectsUnconstrainedWitnesses:

build-debug/.../acir_components_check_tests
Error: attempt to subscript container with out-of-bounds index 10, but container only holds 9 elements.
reference std::vector<unsigned int>::operator[](size_type) [_Tp = unsigned int]
timeout: the monitored command dumped core

Root cause

The test deliberately corrupted the builder to simulate an unconstrained witness:

auto builder = create_circuit<AcirComponentsCheckBuilder>(program);
builder.real_variable_index.resize(9);   // "Corrupt the circuit"

create_circuit produces a builder with many more than 9 variables (the AssertZero over witnesses 8/9, plus pairing-point accumulators). Shrinking real_variable_index to 9 entries leaves it inconsistent with the builder's own gates: those gates still reference variable indices ≥ 9. When ComponentsChecker::check() runs the connected-components analysis, cdg::StaticAnalyzer_::to_real() does real_variable_index[variable_index] over every gate wire and reads past the shrunk vector.

In a release build that unchecked operator[] is a silent out-of-bounds read that happens to leave the test passing; the _GLIBCXX_DEBUG nightly build correctly traps it and aborts. This is undefined behavior in the test, not a defect in the production checker — which is only ever given an internally-consistent builder.

Fix

Test-only change. Instead of corrupting real_variable_index, keep the builder fully consistent (built from a constraint over witnesses 0/1) and feed the checker an ACIR component whose witness indices sit beyond real_variable_index.size(). That witness has no circuit-side variable, so it exercises the same NO_CIRCUIT_CCUNCONSTRAINED path the test intends — which is also the real security property (an ACIR-connected witness missing from the synthesized circuit) — with no out-of-bounds access. The connected-components analysis now runs over an in-bounds builder.

Verification

Reproduced and fixed in a local _GLIBCXX_DEBUG build (cmake --preset debug):

  • Before: DetectsUnconstrainedWitnesses aborts with the out-of-bounds message above.
  • After: DetectsUnconstrainedWitnesses passes; the full acir_components_check_tests suite is green (10/10).

No production code changed.


Created by claudebox · group: slackbot

@AztecBot AztecBot added ci-barretenberg Run all barretenberg/cpp checks. ci-draft Run CI on draft PRs. ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure claudebox Owned by claudebox. it can push to this PR. labels Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-barretenberg Run all barretenberg/cpp checks. ci-draft Run CI on draft PRs. ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure claudebox Owned by claudebox. it can push to this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant