wxwidgets: fix CVE-2024-58249

CVE-2024-58249:
In wxWidgets before 3.2.7, a crash can be triggered in wxWidgets apps when
connections are refused in wxWebRequestCURL.

References:
[https://nvd.nist.gov/vuln/detail/CVE-2024-58249]

Upstream patch:
[f2918a9ac8]

Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
This commit is contained in:
Zhang Peng 2025-11-19 15:54:46 +08:00 committed by Gyorgy Sarvari
parent fb79c60c57
commit 668cef8d6b
2 changed files with 178 additions and 0 deletions

View File

@ -0,0 +1,177 @@
From b60061bb25eb9fb552489185d3e6095106c39755 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Sun, 27 Oct 2024 00:56:21 +0200
Subject: [PATCH] Fix crash when connection is refused in wxWebRequestCURL
Avoid deleting wxEventLoopSourceHandler which may be still in use, as is
the case when we get write IO notification just before an error one: if
we delete the handler while handling the former, we crash when getting
the latter one.
Use a hack to avoid deleting the handlers for which write notification
is being processed and delete them later, when we get the error one.
See #24885.
(cherry picked from commit 4e0fca8ab9756989598d07b41e672af86eac7092)
CVE: CVE-2024-58249
Upstream-Status: Backport [https://github.com/wxWidgets/wxWidgets/commit/f2918a9ac823074901ce27de939baa57788beb3d]
Signed-off-by: Zhang Peng <peng.zhang1.cn@windriver.com>
---
src/common/webrequest_curl.cpp | 80 +++++++++++++++++++++++++---------
1 file changed, 60 insertions(+), 20 deletions(-)
diff --git a/src/common/webrequest_curl.cpp b/src/common/webrequest_curl.cpp
index 91a8aec4ac..b5ffe7a061 100644
--- a/src/common/webrequest_curl.cpp
+++ b/src/common/webrequest_curl.cpp
@@ -685,10 +685,13 @@ SocketPollerImpl* SocketPollerImpl::Create(wxEvtHandler* hndlr)
// SocketPollerSourceHandler - a source handler used by the SocketPoller class.
+class SourceSocketPoller;
+
class SocketPollerSourceHandler: public wxEventLoopSourceHandler
{
public:
- SocketPollerSourceHandler(wxSOCKET_T, wxEvtHandler*);
+ SocketPollerSourceHandler(curl_socket_t sock, SourceSocketPoller* poller)
+ : m_socket(sock), m_poller(poller) {}
void OnReadWaiting() wxOVERRIDE;
void OnWriteWaiting() wxOVERRIDE;
@@ -697,16 +700,9 @@ public:
private:
void SendEvent(int);
wxSOCKET_T m_socket;
- wxEvtHandler* m_handler;
+ SourceSocketPoller* const m_poller;
};
-SocketPollerSourceHandler::SocketPollerSourceHandler(wxSOCKET_T sock,
- wxEvtHandler* hndlr)
-{
- m_socket = sock;
- m_handler = hndlr;
-}
-
void SocketPollerSourceHandler::OnReadWaiting()
{
SendEvent(SocketPoller::READY_FOR_READ);
@@ -722,14 +718,6 @@ void SocketPollerSourceHandler::OnExceptionWaiting()
SendEvent(SocketPoller::HAS_ERROR);
}
-void SocketPollerSourceHandler::SendEvent(int result)
-{
- wxThreadEvent event(wxEVT_SOCKET_POLLER_RESULT);
- event.SetPayload<wxSOCKET_T>(m_socket);
- event.SetInt(result);
- m_handler->ProcessEvent(event);
-}
-
// SourceSocketPoller - a SocketPollerImpl based on event loop sources.
class SourceSocketPoller: public SocketPollerImpl
@@ -741,6 +729,8 @@ public:
void StopPolling(wxSOCKET_T) wxOVERRIDE;
void ResumePolling(wxSOCKET_T) wxOVERRIDE;
+ void SendEvent(curl_socket_t sock, int result);
+
private:
WX_DECLARE_HASH_MAP(wxSOCKET_T, wxEventLoopSource*, wxIntegerHash,\
wxIntegerEqual, SocketDataMap);
@@ -749,11 +739,25 @@ private:
SocketDataMap m_socketData;
wxEvtHandler* m_handler;
+
+ // The socket for which we're currently processing a write IO notification.
+ curl_socket_t m_activeWriteSocket;
+
+ // The sockets that we couldn't clean up yet but should do if/when we get
+ // an error notification for them.
+ wxVector<curl_socket_t> m_socketsToCleanUp;
};
+// This function must be implemented after full SourceSocketPoller declaration.
+void SocketPollerSourceHandler::SendEvent(int result)
+{
+ m_poller->SendEvent(m_socket, result);
+}
+
SourceSocketPoller::SourceSocketPoller(wxEvtHandler* hndlr)
{
m_handler = hndlr;
+ m_activeWriteSocket = 0;
}
SourceSocketPoller::~SourceSocketPoller()
@@ -803,9 +807,7 @@ bool SourceSocketPoller::StartPolling(wxSOCKET_T sock, int pollAction)
}
else
{
- // Otherwise create a new source handler.
- srcHandler =
- new SocketPollerSourceHandler(sock, m_handler);
+ srcHandler = new SocketPollerSourceHandler(sock, this);
}
// Get a new source object for these polling checks.
@@ -839,6 +841,15 @@ bool SourceSocketPoller::StartPolling(wxSOCKET_T sock, int pollAction)
void SourceSocketPoller::StopPolling(wxSOCKET_T sock)
{
+ if ( sock == m_activeWriteSocket )
+ {
+ // We can't clean up the socket while we're inside OnWriteWaiting() for
+ // it because it could be followed by OnExceptionWaiting() and we'd
+ // crash if we deleted it already.
+ m_socketsToCleanUp.push_back(sock);
+ return;
+ }
+
SocketDataMap::iterator it = m_socketData.find(sock);
if ( it != m_socketData.end() )
@@ -852,6 +863,35 @@ void SourceSocketPoller::ResumePolling(wxSOCKET_T WXUNUSED(sock))
{
}
+void SourceSocketPoller::SendEvent(curl_socket_t sock, int result)
+{
+ if ( result == SocketPoller::READY_FOR_WRITE )
+ {
+ // Prevent the handler from this socket from being deleted in case we
+ // get a HAS_ERROR event for it immediately after this one.
+ m_activeWriteSocket = sock;
+ }
+
+ wxThreadEvent event(wxEVT_SOCKET_POLLER_RESULT);
+ event.SetPayload<curl_socket_t>(sock);
+ event.SetInt(result);
+ m_handler->ProcessEvent(event);
+
+ m_activeWriteSocket = 0;
+
+ if ( result == SocketPoller::HAS_ERROR )
+ {
+ // Check if we have any sockets to clean up and do it now, it should be
+ // safe.
+ for ( size_t n = 0; n < m_socketsToCleanUp.size(); ++n )
+ {
+ StopPolling(m_socketsToCleanUp[n]);
+ }
+
+ m_socketsToCleanUp.clear();
+ }
+}
+
void SourceSocketPoller::CleanUpSocketSource(wxEventLoopSource* source)
{
wxEventLoopSourceHandler* srcHandler = source->GetHandler();
--
2.50.0

View File

@ -25,6 +25,7 @@ SRC_URI = " \
file://respect-DESTDIR-when-create-link.patch \
file://not-append-system-name-to-lib-name.patch \
file://wx-config-fix-libdir-for-multilib.patch \
file://CVE-2024-58249.patch \
"
SRCREV= "9c0a8be1dc32063d91ed1901fd5fcd54f4f955a1"
S = "${WORKDIR}/git"