Don't store "this" in static variable

Fix #1960

This could also cause use-after-free if the first connected socket disconnects
This commit is contained in:
Alexey Sokolov
2025-06-23 22:41:08 +01:00
parent 7eaa3048b3
commit 7b7f691213
2 changed files with 37 additions and 12 deletions

View File

@@ -408,22 +408,28 @@ bool CIRCSock::OnCapabilityMessage(CMessage& Message) {
sArgs = Message.GetParam(2);
}
static std::map<CString, std::function<void(bool bVal)>> mSupportedCaps = {
{"multi-prefix", [this](bool bVal) { m_bNamesx = bVal; }},
{"userhost-in-names", [this](bool bVal) { m_bUHNames = bVal; }},
{"cap-notify", [](bool bVal) {}},
{"invite-notify", [](bool bVal) {}},
{"server-time", [this](bool bVal) { m_bServerTime = bVal; }},
{"znc.in/server-time-iso", [this](bool bVal) { m_bServerTime = bVal; }},
{"chghost", [](bool) {}},
{"message-tags", [this](bool bVal) { m_bMessageTagCap = bVal; }},
};
static std::map<CString, std::function<void(CIRCSock * pSock, bool bVal)>>
mSupportedCaps = {
{"multi-prefix",
[](CIRCSock* pSock, bool bVal) { pSock->m_bNamesx = bVal; }},
{"userhost-in-names",
[](CIRCSock* pSock, bool bVal) { pSock->m_bUHNames = bVal; }},
{"cap-notify", [](CIRCSock* pSock, bool bVal) {}},
{"invite-notify", [](CIRCSock* pSock, bool bVal) {}},
{"server-time",
[](CIRCSock* pSock, bool bVal) { pSock->m_bServerTime = bVal; }},
{"znc.in/server-time-iso",
[](CIRCSock* pSock, bool bVal) { pSock->m_bServerTime = bVal; }},
{"chghost", [](CIRCSock* pSock, bool) {}},
{"message-tags", [](CIRCSock* pSock,
bool bVal) { pSock->m_bMessageTagCap = bVal; }},
};
auto RemoveCap = [&](const CString& sCap) {
IRCSOCKMODULECALL(OnServerCapResult(sCap, false), NOTHING);
auto it = mSupportedCaps.find(sCap);
if (it != mSupportedCaps.end()) {
it->second(false);
it->second(this, false);
}
m_ssAcceptedCaps.erase(sCap);
m_ssPendingCaps.erase(sCap);
@@ -457,7 +463,7 @@ bool CIRCSock::OnCapabilityMessage(CMessage& Message) {
IRCSOCKMODULECALL(OnServerCapResult(sCap, true), NOTHING);
auto it = mSupportedCaps.find(sCap);
if (it != mSupportedCaps.end()) {
it->second(true);
it->second(this, true);
}
m_ssAcceptedCaps.insert(std::move(sCap));
}

View File

@@ -1191,5 +1191,24 @@ TEST_F(ZNCTest, JoinWhileRegistration) {
ircd.ReadUntil("JOIN #foo");
}
TEST_F(ZNCTest, Issue1960) {
auto znc = Run();
auto ircd1 = ConnectIRCd();
auto client = LoginClient();
ircd1.Write("CAP user ACK :message-tags");
ircd1.Write(":server 001 nick :Hello");
ircd1.Write(":server 005 nick blahblah");
client.ReadUntil("blahblah");
client.Write("znc addnetwork second");
client.Write("znc jumpnetwork second");
client.Write("znc addserver unix:" + m_dir.path().toUtf8() + "/inttest.ircd");
auto ircd2 = ConnectIRCd();
ircd2.Write("CAP user ACK :message-tags");
ircd2.Write(":server 001 nick :Hello");
client.ReadUntil("Connected");
client.Write("@foo TAGMSG #bar");
ircd2.ReadUntil("@foo TAGMSG #bar");
}
} // namespace
} // namespace znc_inttest