|
From: <fli...@li...> - 2026-07-29 09:11:12
|
unknown user pushed a commit to branch release/2024.1
in repository flightgear.
The following commit(s) were added to refs/heads/release/2024.1 by this push:
new ceb1a5de8 Fix a crash when closing many props channels
ceb1a5de8 is described below
SF URL: http://sourceforge.net/p/flightgear/flightgear/ci/ceb1a5de81f295d84a449e4409b69910d9c7a016/
Commit: ceb1a5de81f295d84a449e4409b69910d9c7a016
Author: James Turner
Committer: James Turner
AuthorDate: Wed Jul 29 09:16:08 2026 +0100
Fix a crash when closing many props channels
---
src/Network/propsProtocol.cxx | 14 +++++++++-----
src/Network/propsProtocol.hxx | 6 +++---
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/Network/propsProtocol.cxx b/src/Network/propsProtocol.cxx
index edc403f27..90a0b1282 100644
--- a/src/Network/propsProtocol.cxx
+++ b/src/Network/propsProtocol.cxx
@@ -819,11 +819,15 @@ bool FGProps::close()
// guard this, since NetChannelPoller::removeChannel must be symmetric
if (is_enabled()) {
SG_LOG(SG_IO, SG_INFO, "closing FGProps");
- for (auto channel : _activeChannels) {
+ // Swap out _activeChannels before iterating: ~PropsChannel calls removeChannel()
+ // which would otherwise modify _activeChannels during the range-for loop,
+ // causing iterator invalidation and potential use-after-free with 3+ connections.
+ std::vector<PropsChannel*> toClose;
+ std::swap(toClose, _activeChannels);
+ for (auto channel : toClose) {
channel->close();
delete channel;
}
- _activeChannels.clear();
poller.removeChannel(this);
set_enabled(false);
@@ -864,9 +868,9 @@ void FGProps::handleAccept()
void FGProps::removeChannel(FGProps::PropsChannel* channel)
{
auto it = std::find(_activeChannels.begin(), _activeChannels.end(), channel);
- if (it == _activeChannels.end()) {
- SG_LOG(SG_IO, SG_WARN, "FGProps::removeChannel: unknown channel");
- } else {
+ if (it != _activeChannels.end()) {
_activeChannels.erase(it);
}
+ // not finding the channel is expected when called from ~PropsChannel
+ // during FGProps::close(), since _activeChannels has been swapped out
}
diff --git a/src/Network/propsProtocol.hxx b/src/Network/propsProtocol.hxx
index 14733f194..9d51e7fe8 100644
--- a/src/Network/propsProtocol.hxx
+++ b/src/Network/propsProtocol.hxx
@@ -39,7 +39,7 @@ private:
public:
/**
* Create a new TCP server.
- *
+ *
* @param tokens Tokenized configuration parameters
*/
FGProps(const std::vector<std::string>& tokens);
@@ -47,7 +47,7 @@ public:
/**
* Destructor.
*/
- ~FGProps();
+ virtual ~FGProps();
/**
* Start the telnet server.
@@ -60,7 +60,7 @@ public:
bool process() override;
/**
- *
+ *
*/
bool close() override;
|