Skip to content

odb: UnfoldedModel as a persistent object in dbDatabase#9639

Open
osamahammad21 wants to merge 4 commits intoThe-OpenROAD-Project:masterfrom
osamahammad21:odb-unfolded-model
Open

odb: UnfoldedModel as a persistent object in dbDatabase#9639
osamahammad21 wants to merge 4 commits intoThe-OpenROAD-Project:masterfrom
osamahammad21:odb-unfolded-model

Conversation

@osamahammad21
Copy link
Member

No description provided.

Signed-off-by: osamahammad21 <osama21@aucegypt.edu>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the creation of UnfoldedModel to be a persistent, lazily-initialized object within dbDatabase, which is a good change for performance. However, the current implementation introduces a high-severity Use-After-Free vulnerability due to the lack of an invalidation mechanism when the underlying database is modified. This also leads to cache staleness, potentially returning incorrect data. Furthermore, the lazy initialization is not thread-safe, which can cause race conditions, and a potential null pointer dereference was identified in the Checker::check method when operating on an empty database. These issues need to be addressed to ensure correctness, stability, and security.

Comment on lines +694 to +701
UnfoldedModel* dbDatabase::getUnfoldedModel()
{
_dbDatabase* db = (_dbDatabase*) this;
if (db->unfolded_model_ == nullptr) {
db->unfolded_model_ = new UnfoldedModel(db->logger_, getChip());
}
return db->unfolded_model_;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

This section of code is susceptible to a Use-After-Free vulnerability. The UnfoldedModel is a persistent, lazily-initialized object, but it lacks an invalidation mechanism. When the underlying database (e.g., dbChip or its components) is modified, the UnfoldedModel can retain dangling pointers to deleted objects, leading to crashes or unpredictable behavior upon access. Additionally, this results in stale data being returned. To remediate this, an invalidation mechanism must be implemented. The unfolded_model_ should be deleted and set to nullptr whenever the database structure is modified (e.g., via observers, explicitly clearing it in modification methods, or by adding an invalidateUnfoldedModel() method to dbDatabase and calling it after relevant structural changes).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected

Signed-off-by: osamahammad21 <osama21@aucegypt.edu>
Signed-off-by: osamahammad21 <osama21@aucegypt.edu>
Signed-off-by: osamahammad21 <osama21@aucegypt.edu>
@osamahammad21 osamahammad21 requested a review from maliberty March 8, 2026 21:24
@osamahammad21
Copy link
Member Author

@ahmed532 @jferreiraOpenRoad FYI

@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

clang-tidy review says "All clean, LGTM! 👍"

void dbDatabase::constructUnfoldedModel()
{
_dbDatabase* db = (_dbDatabase*) this;
absl::MutexLock lock(unfolded_model_mutex);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general odb doesn't support MT access. Do we need it here?

If so we need to guard against the model already being created by the previous locker. Also getUnfoldedModel will need a lock.

return (dbChip*) db->chip_tbl_->getPtr(db->chip_);
}

void dbDatabase::constructUnfoldedModel()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we have auto creation in get rather than explicit construction? Do we want get to return a nullptr?


utl::Logger* logger_;
std::set<dbDatabaseObserver*> observers_;
UnfoldedModel* unfolded_model_;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mention that it is non-persistent

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