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.

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

Upstream patches:
[https://github.com/wxWidgets/wxWidgets/commit/f2918a9ac823074901ce27de939baa57788beb3d]

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-07-24 17:23:42 +08:00
committed by Gyorgy Sarvari
parent d35cbff11e
commit d3d3df49d5
2 changed files with 179 additions and 0 deletions
@@ -0,0 +1,178 @@
From e440b3a6097546a8aca66bd4c7a21be25e89d340 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 f50acf4f8d..64650ab6b4 100644
--- a/src/common/webrequest_curl.cpp
+++ b/src/common/webrequest_curl.cpp
@@ -704,10 +704,13 @@ SocketPollerImpl* SocketPollerImpl::Create(wxEvtHandler* hndlr)
// SocketPollerSourceHandler - a source handler used by the SocketPoller class.
+class SourceSocketPoller;
+
class SocketPollerSourceHandler: public wxEventLoopSourceHandler
{
public:
- SocketPollerSourceHandler(curl_socket_t, wxEvtHandler*);
+ SocketPollerSourceHandler(curl_socket_t sock, SourceSocketPoller* poller)
+ : m_socket(sock), m_poller(poller) {}
void OnReadWaiting() wxOVERRIDE;
void OnWriteWaiting() wxOVERRIDE;
@@ -716,16 +719,9 @@ public:
private:
void SendEvent(int);
curl_socket_t m_socket;
- wxEvtHandler* m_handler;
+ SourceSocketPoller* const m_poller;
};
-SocketPollerSourceHandler::SocketPollerSourceHandler(curl_socket_t sock,
- wxEvtHandler* hndlr)
-{
- m_socket = sock;
- m_handler = hndlr;
-}
-
void SocketPollerSourceHandler::OnReadWaiting()
{
SendEvent(SocketPoller::READY_FOR_READ);
@@ -741,14 +737,6 @@ void SocketPollerSourceHandler::OnExceptionWaiting()
SendEvent(SocketPoller::HAS_ERROR);
}
-void SocketPollerSourceHandler::SendEvent(int result)
-{
- wxThreadEvent event(wxEVT_SOCKET_POLLER_RESULT);
- event.SetPayload<curl_socket_t>(m_socket);
- event.SetInt(result);
- m_handler->ProcessEvent(event);
-}
-
// SourceSocketPoller - a SocketPollerImpl based on event loop sources.
class SourceSocketPoller: public SocketPollerImpl
@@ -760,6 +748,8 @@ public:
void StopPolling(curl_socket_t) wxOVERRIDE;
void ResumePolling(curl_socket_t) wxOVERRIDE;
+ void SendEvent(curl_socket_t sock, int result);
+
private:
WX_DECLARE_HASH_MAP(curl_socket_t, wxEventLoopSource*, wxIntegerHash,\
wxIntegerEqual, SocketDataMap);
@@ -768,11 +758,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()
@@ -822,9 +826,7 @@ bool SourceSocketPoller::StartPolling(curl_socket_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.
@@ -858,6 +860,15 @@ bool SourceSocketPoller::StartPolling(curl_socket_t sock, int pollAction)
void SourceSocketPoller::StopPolling(curl_socket_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() )
@@ -871,6 +882,35 @@ void SourceSocketPoller::ResumePolling(curl_socket_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
@@ -26,6 +26,7 @@ SRC_URI = "gitsm://github.com/wxWidgets/wxWidgets.git;branch=3.2;protocol=https
file://0005-wx-config-fix-libdir-for-multilib.patch \
file://0006-Fix-locale-on-musl.patch \
file://0007-Set-HAVE_LARGEFILE_SUPPORT-to-1-explicitly.patch \
file://CVE-2024-58249.patch \
"
SRCREV = "5ff25322553c1870cf20a2e1ba6f20ed50d9fe9a"
S = "${WORKDIR}/git"