mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-25 01:41:43 +00:00
[ntcore] Fix use-after-free on connection termination (#7177)
The stream can close (e.g. due to an error) while in the middle of writing. The close callback would immediately destroy the connection object, resulting in the writing code having a use-after-free. Fix this by deferring the deletion to the loop main using a single-shot timer.
This commit is contained in:
@@ -125,7 +125,9 @@ void NetworkServer::ServerConnection::UpdateOutgoingTimer(uint32_t repeatMs) {
|
||||
void NetworkServer::ServerConnection::ConnectionClosed() {
|
||||
// don't call back into m_server if it's being destroyed
|
||||
if (!m_outgoingTimer->IsLoopClosing()) {
|
||||
m_server.m_serverImpl.RemoveClient(m_clientId);
|
||||
uv::Timer::SingleShot(m_outgoingTimer->GetLoopRef(), uv::Timer::Time{0},
|
||||
[client = m_server.m_serverImpl.RemoveClient(
|
||||
m_clientId)]() mutable { client.reset(); });
|
||||
m_server.RemoveConnection(this);
|
||||
}
|
||||
m_outgoingTimer->Close();
|
||||
|
||||
@@ -1252,7 +1252,7 @@ int ServerImpl::AddClient3(std::string_view connInfo, bool local,
|
||||
return index;
|
||||
}
|
||||
|
||||
void ServerImpl::RemoveClient(int clientId) {
|
||||
std::shared_ptr<void> ServerImpl::RemoveClient(int clientId) {
|
||||
DEBUG3("RemoveClient({})", clientId);
|
||||
auto& client = m_clients[clientId];
|
||||
|
||||
@@ -1288,8 +1288,7 @@ void ServerImpl::RemoveClient(int clientId) {
|
||||
DeleteTopic(client->m_metaPub);
|
||||
DeleteTopic(client->m_metaSub);
|
||||
|
||||
// delete the client
|
||||
client.reset();
|
||||
return std::move(client);
|
||||
}
|
||||
|
||||
bool ServerImpl::PersistentChanged() {
|
||||
|
||||
@@ -80,7 +80,7 @@ class ServerImpl final {
|
||||
int AddClient3(std::string_view connInfo, bool local,
|
||||
net3::WireConnection3& wire, Connected3Func connected,
|
||||
SetPeriodicFunc setPeriodic);
|
||||
void RemoveClient(int clientId);
|
||||
std::shared_ptr<void> RemoveClient(int clientId);
|
||||
|
||||
void ConnectionsChanged(const std::vector<ConnectionInfo>& conns);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user