Skip to content

Commit 606343a

Browse files
committed
rsz: add cpp test guarding prevArc()->from() driver-input port lookup
Regression guard for the issue #10210 fix in SizeUpMove: the driver input LibertyPort is now resolved via drvr_path->prevArc()->from() (using prev_edge_id_ / prev_arc_idx_ stored on the Path itself) instead of drvr_path->prevPath()->pin(), which dereferenced a raw prev_path_ pointer vulnerable to dangling after paths_ realloc. This test uses the existing BufRemTest buffer chain, constrains timing with a virtual clock + output delay, then checks that prevArc()->from() returns the same LibertyPort as network_->libertyPort( driver_input_pin). It does not attempt to reproduce the UAF (which requires ASAN + a full multi-corner repair_timing run) but pins the semantic contract the fix relies on, so a future refactor that substitutes the wrong arc/port would fail here. Signed-off-by: Minju Kim <mkim@precisioninno.com>
1 parent 7282ca3 commit 606343a

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

src/rsz/test/cpp/TestBufferRemoval.cc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@
2424
#include "sta/Graph.hh"
2525
#include "sta/Liberty.hh"
2626
#include "sta/NetworkClass.hh"
27+
#include "sta/Path.hh"
2728
#include "sta/Search.hh"
2829
#include "sta/SearchClass.hh"
2930
#include "sta/Sta.hh"
31+
#include "sta/TimingArc.hh"
3032
#include "stt/SteinerTreeBuilder.h"
3133
#include "tst/fixture.h"
3234
#include "tst/nangate45_fixture.h"
@@ -167,4 +169,34 @@ TEST_F(BufRemTest, SlackImproves)
167169
EXPECT_EQ(restoredArrival, origArrival);
168170
}
169171

172+
// Regression guard for #10210: SizeUpMove used drvr_path->prevPath()->pin()
173+
// which could dangle after paths_ realloc; prevArc()->from() resolves the same
174+
// driver-input LibertyPort via data stored on the Path itself.
175+
TEST_F(BufRemTest, PrevArcFromMatchesDriverInputPort)
176+
{
177+
sta::Graph* graph = sta_->ensureGraph();
178+
sta::Network* network = sta_->network();
179+
sta_->updateTiming(true);
180+
181+
odb::dbInst* b3_db = block_->findInst("b3");
182+
ASSERT_NE(b3_db, nullptr);
183+
sta::Instance* b3 = db_network_->dbToSta(b3_db);
184+
sta::Pin* b3_z = network->findPin(b3, "Z");
185+
sta::Pin* b3_a = network->findPin(b3, "A");
186+
ASSERT_NE(b3_z, nullptr);
187+
ASSERT_NE(b3_a, nullptr);
188+
189+
sta::Vertex* b3_z_vertex = graph->pinDrvrVertex(b3_z);
190+
ASSERT_NE(b3_z_vertex, nullptr);
191+
192+
sta::Path* drvr_path
193+
= sta_->vertexWorstArrivalPath(b3_z_vertex, sta::MinMax::max());
194+
ASSERT_NE(drvr_path, nullptr);
195+
ASSERT_FALSE(drvr_path->isNull());
196+
197+
const sta::TimingArc* in_arc = drvr_path->prevArc(sta_.get());
198+
ASSERT_NE(in_arc, nullptr);
199+
EXPECT_EQ(in_arc->from(), network->libertyPort(b3_a));
200+
}
201+
170202
} // namespace rsz

0 commit comments

Comments
 (0)