Skip to content

Fix uninitialized read in lut_map on networks with dangling nodes - #707

Merged
myskyko merged 2 commits into
lsils:masterfrom
marcelwa:fix-lutmap-uninit-cut
Sep 29, 2026
Merged

myskyko merged 2 commits into
lsils:masterfrom
marcelwa:fix-lutmap-uninit-cut

Conversation

@marcelwa

@marcelwa marcelwa commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Area-oriented lut_map can read uninitialized memory and crash when a network contains nodes unreachable from its outputs, because mapping initialization accesses those nodes' empty cut sets through best(). Initialize only the first cut's leaf range and metadata in cut_set::clear() and lut_cut_set::clear(), keeping the default cut constructor and providing a defined empty cut after construction or clearing. The dangling-node regression and new tests for fresh and cleared, previously populated cut sets pass locally alongside the cut-enumeration tests (30 test cases, 218 assertions).

@codecov

codecov Bot commented Aug 30, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.09%. Comparing base (d9e0249) to head (3586273).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #707   +/-   ##
=======================================
  Coverage   84.08%   84.09%           
=======================================
  Files         191      191           
  Lines       29575    29579    +4     
=======================================
+ Hits        24867    24873    +6     
+ Misses       4708     4706    -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@myskyko

myskyko commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator

It seems to include various unrelated changes. Can you trim those or split into other PRs to help me review?

@myskyko

myskyko commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator

Also FYI I'm going to update fmt to a newer version (12.1.0).

`cut() = default` leaves `_length`, `_cend` and `_end` indeterminate.  A
default-constructed cut is reachable: `cut_set` and `lut_cut_set` hold an array
of them and `best()` returns `*_pcuts[0]` whether or not any cut has been
inserted.  `lut_map_impl::compute_share_mapping_init` iterates over every node
index and calls `best()`, and a node unreachable from the outputs is never
visited by the cut enumerator, so its cut set is empty and the following
`for ( auto leaf : cut )` in `compute_cut_data` walks a garbage end pointer and
indexes `cuts[leaf]` with whatever it finds.

Networks with unreachable nodes are not exotic: ABC's `&dch -f; &put` leaves the
choice-class members in as ordinary AND nodes, so every AIG written by the
standard `strash; &get; &dch -f; &put; write_aiger` front end has them (cavlc:
1271 ANDs written, 647 reachable).

Give the default constructor a defined empty state, and add a lut_mapper test
that maps a six-gate AIG whose last four gates drive no output.
@marcelwa
marcelwa force-pushed the fix-lutmap-uninit-cut branch from 8d96a76 to f512088 Compare September 24, 2026 09:36
@marcelwa

Copy link
Copy Markdown
Contributor Author

It seems to include various unrelated changes. Can you trim those or split into other PRs to help me review?

Sorry for the mess. That was of course unintended. I got quite some local changes into the PR on accident. It's cleaned up now.

@marcelwa marcelwa changed the title Fix uninitialised read in lut_map on networks with dangling nodes Fix uninitialized read in lut_map on networks with dangling nodes Sep 24, 2026
@myskyko

myskyko commented Sep 28, 2026

Copy link
Copy Markdown
Collaborator

Maybe it is a negligible overhead, but isn't setting the constructor to cut overkill?
If the access to the uninitialized entry is only the issue of cut_set rather than cut itself, should we set the members of _cuts[0] in clear() of cut_set?

@marcelwa

Copy link
Copy Markdown
Contributor Author

That’s a fair point. I benchmarked both approaches on five EPFL circuits and found small, mixed differences in total mapping time, with no consistent advantage either way. Initializing only the first cut in clear() is narrower and also handles clearing a previously populated set, so I’ll switch to that approach.

@marcelwa
marcelwa force-pushed the fix-lutmap-uninit-cut branch from e543cc3 to 3586273 Compare September 28, 2026 17:29
@myskyko
myskyko merged commit 47d1e70 into lsils:master Sep 29, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants