Dict: Invalidate iterators during Clear()

If we don't do this, a RobustDictIterator owned by someone else holds
dangling pointers to the Dictionary that is being cleared.

Closes #3523
This commit is contained in:
Arne Welzel 2024-01-08 14:44:08 +01:00
parent 985e1f9024
commit 96823dab73
3 changed files with 23 additions and 1 deletions

View file

@ -382,7 +382,9 @@ public:
pointer operator->() { return &curr; }
RobustDictIterator& operator++() {
if ( dict )
curr = dict->GetNextRobustIteration(this);
return *this;
}
@ -475,6 +477,7 @@ private:
inserted = nullptr;
visited = nullptr;
dict = nullptr;
curr = nullptr; // make this same as robust_end()
}
}
@ -765,6 +768,11 @@ public:
order.reset();
if ( iterators ) {
// Complete() erases from this Dictionary's iterators member, use a copy.
auto copied_iterators = *iterators;
for ( auto* i : copied_iterators )
i->Complete();
delete iterators;
iterators = nullptr;
}

View file

@ -0,0 +1,14 @@
# @TEST-EXEC: zcat <$TRACES/smb/smb_many_open_files_500.pcap.gz | zeek -b -Cr - %INPUT
# @TEST-DOC: Regression test #3523; no output check, just shouldn't crash
redef table_expire_delay = 0.1sec;
redef table_incremental_step = 1;
redef table_expire_interval = 0.1sec;
redef record connection += {
recent_tcp: set[string] &default=set() &read_expire=3min;
};
event new_packet(c: connection, pkt: pkt_hdr) {
add c$recent_tcp[cat(pkt$tcp)];
}