Prevent use-after-free crashes by not fighting over who owns a HOLE.

The diff-pair placer creates DIFF_PAIRs on the stack, which have
VIAs in them, which have HOLEs in them.  The HOLEs get put in the
NODE's index, and we then crash later when doing a collision after
the stack variable has gone out of scope.

The stack variable is also copied while doing a search for "best",
and without the operator= definitions the "best" and the "original"
both think they own the HOLE.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/14852
This commit is contained in:
Jeff Young 2023-06-01 15:06:09 +01:00
parent 2300b0d2a3
commit deb3cbf89b
3 changed files with 36 additions and 2 deletions

View File

@ -518,8 +518,11 @@ void NODE::addHole( HOLE* aHole )
// do we need holes in the connection graph?
//linkJoint( aHole->Pos(), aHole->Layers(), aHole->Net(), aHole );
aHole->SetOwner( this );
m_index->Add( aHole );
HOLE* hole = new HOLE( aHole->Shape()->Clone() );
hole->SetLayers( aHole->Layers() );
hole->SetOwner( this );
m_index->Add( hole );
}

View File

@ -66,6 +66,20 @@ public:
m_orientation = aSolid.m_orientation;
}
SOLID& operator=( const SOLID& aB )
{
if( aB.m_shape )
SetShape( aB.m_shape->Clone() );
if( aB.m_hole )
SetHole( new PNS::HOLE( aB.m_hole->Shape()->Clone() ) );
m_pos = aB.m_pos;
m_padToDie = aB.m_padToDie;
m_orientation = aB.m_orientation;
return *this;
}
static inline bool ClassOf( const ITEM* aItem )
{
return aItem && SOLID_T == aItem->Kind();

View File

@ -103,6 +103,23 @@ public:
delete m_hole;
}
VIA& operator=( const VIA& aB )
{
SetNet( aB.Net() );
SetLayers( aB.Layers() );
m_pos = aB.m_pos;
m_diameter = aB.m_diameter;
m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 );
m_drill = aB.m_drill;
SetHole( HOLE::MakeCircularHole( m_pos, m_drill / 2 ) );
m_marker = aB.m_marker;
m_rank = aB.m_rank;
m_viaType = aB.m_viaType;
m_isFree = aB.m_isFree;
m_isVirtual = aB.m_isVirtual;
return *this;
}
static inline bool ClassOf( const ITEM* aItem )
{
return aItem && VIA_T == aItem->Kind();