import Oracle_OSS freerdp-3.10.3-12.el10_2.6
This commit is contained in:
parent
6b0a8dd639
commit
5335061a79
143
channels-cliprdr-abort-on-duplicate-caps.patch
Normal file
143
channels-cliprdr-abort-on-duplicate-caps.patch
Normal file
@ -0,0 +1,143 @@
|
||||
From abf9e9c31e64630aa7459ac22e1aff3a277fd830 Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <armin.novak@thincast.com>
|
||||
Date: Thu, 30 Apr 2026 10:42:42 +0200
|
||||
Subject: [PATCH] [channels,cliprdr] abort on duplicate caps
|
||||
|
||||
---
|
||||
channels/cliprdr/server/cliprdr_main.c | 70 +++++++++++++++-----------
|
||||
1 file changed, 42 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c
|
||||
index 1aef5b373..345236d27 100644
|
||||
--- a/channels/cliprdr/server/cliprdr_main.c
|
||||
+++ b/channels/cliprdr/server/cliprdr_main.c
|
||||
@@ -472,6 +472,15 @@ static UINT cliprdr_server_receive_general_capability(CliprdrServerContext* cont
|
||||
WINPR_ASSERT(context);
|
||||
WINPR_ASSERT(cap_set);
|
||||
|
||||
+ if (cap_set->capabilitySetLength != sizeof(CLIPRDR_GENERAL_CAPABILITY_SET))
|
||||
+ {
|
||||
+ WLog_ERR(TAG,
|
||||
+ "invalid capabilitySetLength %" PRIu16 " != %" PRIuz
|
||||
+ " (capabilitySetType=CB_CAPSTYPE_GENERAL)",
|
||||
+ cap_set->capabilitySetLength, sizeof(CLIPRDR_GENERAL_CAPABILITY_SET));
|
||||
+ return ERROR_INVALID_DATA;
|
||||
+ }
|
||||
+
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
@@ -500,6 +509,26 @@ static UINT cliprdr_server_receive_general_capability(CliprdrServerContext* cont
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
+static BOOL cliprdr_capabilities_contain_capset(const CLIPRDR_CAPABILITIES* capabilities,
|
||||
+ const CLIPRDR_CAPABILITY_SET* capset)
|
||||
+{
|
||||
+ WINPR_ASSERT(capabilities);
|
||||
+
|
||||
+ const BYTE* offset = (const BYTE*)capabilities->capabilitySets;
|
||||
+ for (UINT32 x = 0; x < capabilities->cCapabilitiesSets; x++)
|
||||
+ {
|
||||
+ const CLIPRDR_CAPABILITY_SET* cur = (const CLIPRDR_CAPABILITY_SET*)offset;
|
||||
+ offset += cur->capabilitySetLength;
|
||||
+
|
||||
+ if (cur->capabilitySetType == capset->capabilitySetType)
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "duplicate CLIPRDR_CAPABILITY_SET %" PRIu16, cur->capabilitySetType);
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
@@ -508,12 +537,9 @@ static UINT cliprdr_server_receive_general_capability(CliprdrServerContext* cont
|
||||
static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, wStream* s,
|
||||
const CLIPRDR_HEADER* header)
|
||||
{
|
||||
- UINT16 capabilitySetType = 0;
|
||||
- UINT16 capabilitySetLength = 0;
|
||||
UINT error = ERROR_INVALID_DATA;
|
||||
size_t cap_sets_size = 0;
|
||||
CLIPRDR_CAPABILITIES capabilities = { 0 };
|
||||
- CLIPRDR_CAPABILITY_SET* capSet = NULL;
|
||||
|
||||
WINPR_ASSERT(context);
|
||||
WINPR_UNUSED(header);
|
||||
@@ -522,17 +548,16 @@ static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, w
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
- Stream_Read_UINT16(s, capabilities.cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */
|
||||
+ const UINT16 cCapabilitiesSets = Stream_Get_UINT16(s); /* cCapabilitiesSets (2 bytes) */
|
||||
Stream_Seek_UINT16(s); /* pad1 (2 bytes) */
|
||||
|
||||
- for (size_t index = 0; index < capabilities.cCapabilitiesSets; index++)
|
||||
+ for (size_t index = 0; index < cCapabilitiesSets; index++)
|
||||
{
|
||||
- void* tmp = NULL;
|
||||
const size_t cap_set_offset = cap_sets_size;
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(CLIPRDR_CAPABILITY_SET)))
|
||||
goto out;
|
||||
- Stream_Read_UINT16(s, capabilitySetType); /* capabilitySetType (2 bytes) */
|
||||
- Stream_Read_UINT16(s, capabilitySetLength); /* capabilitySetLength (2 bytes) */
|
||||
+ const UINT16 capabilitySetType = Stream_Get_UINT16(s); /* capabilitySetType (2 bytes) */
|
||||
+ const UINT16 capabilitySetLength = Stream_Get_UINT16(s); /* capabilitySetLength (2 bytes) */
|
||||
|
||||
if (capabilitySetLength < sizeof(CLIPRDR_CAPABILITY_SET))
|
||||
{
|
||||
@@ -547,26 +572,9 @@ static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, w
|
||||
TAG, s, (size_t)capabilitySetLength - sizeof(CLIPRDR_CAPABILITY_SET)))
|
||||
goto out;
|
||||
|
||||
- switch (capabilitySetType)
|
||||
- {
|
||||
- case CB_CAPSTYPE_GENERAL:
|
||||
- if (capabilitySetLength != sizeof(CLIPRDR_GENERAL_CAPABILITY_SET))
|
||||
- {
|
||||
- WLog_ERR(TAG,
|
||||
- "invalid capabilitySetLength %" PRIu16 " != %" PRIuz
|
||||
- " (capabilitySetType=CB_CAPSTYPE_GENERAL)",
|
||||
- capabilitySetLength, sizeof(CLIPRDR_GENERAL_CAPABILITY_SET));
|
||||
- goto out;
|
||||
- }
|
||||
- break;
|
||||
- default:
|
||||
- WLog_ERR(TAG, "unknown cliprdr capability set: %" PRIu16 "", capabilitySetType);
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
cap_sets_size += capabilitySetLength;
|
||||
|
||||
- tmp = realloc(capabilities.capabilitySets, cap_sets_size);
|
||||
+ CLIPRDR_CAPABILITY_SET* tmp = realloc(capabilities.capabilitySets, cap_sets_size);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
WLog_ERR(TAG, "capabilities.capabilitySets realloc failed!");
|
||||
@@ -574,13 +582,19 @@ static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, w
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
- capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*)tmp;
|
||||
+ capabilities.capabilitySets = tmp;
|
||||
|
||||
- capSet = (CLIPRDR_CAPABILITY_SET*)(((BYTE*)capabilities.capabilitySets) + cap_set_offset);
|
||||
+ CLIPRDR_CAPABILITY_SET* capSet =
|
||||
+ (CLIPRDR_CAPABILITY_SET*)(((BYTE*)capabilities.capabilitySets) + cap_set_offset);
|
||||
|
||||
capSet->capabilitySetType = capabilitySetType;
|
||||
capSet->capabilitySetLength = capabilitySetLength;
|
||||
|
||||
+ if (cliprdr_capabilities_contain_capset(&capabilities, capSet))
|
||||
+ goto out;
|
||||
+
|
||||
+ capabilities.cCapabilitiesSets++;
|
||||
+
|
||||
switch (capSet->capabilitySetType)
|
||||
{
|
||||
case CB_CAPSTYPE_GENERAL:
|
||||
--
|
||||
2.52.0
|
||||
@ -0,0 +1,73 @@
|
||||
From ff87e97d62f699826f6b8fc8f754e979d2c87ecb Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Valerio <kvalerio@protonmail.com>
|
||||
Date: Wed, 29 Apr 2026 22:39:54 +0200
|
||||
Subject: [PATCH] fix(cliprdr): validate capabilitySetLength in server caps
|
||||
|
||||
---
|
||||
channels/cliprdr/server/cliprdr_main.c | 38 +++++++++++++++++++++++---
|
||||
1 file changed, 34 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c
|
||||
index 3cfa057e3..1aef5b373 100644
|
||||
--- a/channels/cliprdr/server/cliprdr_main.c
|
||||
+++ b/channels/cliprdr/server/cliprdr_main.c
|
||||
@@ -528,15 +528,45 @@ static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, w
|
||||
for (size_t index = 0; index < capabilities.cCapabilitiesSets; index++)
|
||||
{
|
||||
void* tmp = NULL;
|
||||
- if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
|
||||
+ const size_t cap_set_offset = cap_sets_size;
|
||||
+ if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(CLIPRDR_CAPABILITY_SET)))
|
||||
goto out;
|
||||
Stream_Read_UINT16(s, capabilitySetType); /* capabilitySetType (2 bytes) */
|
||||
Stream_Read_UINT16(s, capabilitySetLength); /* capabilitySetLength (2 bytes) */
|
||||
|
||||
+ if (capabilitySetLength < sizeof(CLIPRDR_CAPABILITY_SET))
|
||||
+ {
|
||||
+ WLog_ERR(TAG,
|
||||
+ "invalid capabilitySetLength %" PRIu16 " < %" PRIuz
|
||||
+ " (capabilitySetType=%" PRIu16 ")",
|
||||
+ capabilitySetLength, sizeof(CLIPRDR_CAPABILITY_SET), capabilitySetType);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (!Stream_CheckAndLogRequiredLength(
|
||||
+ TAG, s, (size_t)capabilitySetLength - sizeof(CLIPRDR_CAPABILITY_SET)))
|
||||
+ goto out;
|
||||
+
|
||||
+ switch (capabilitySetType)
|
||||
+ {
|
||||
+ case CB_CAPSTYPE_GENERAL:
|
||||
+ if (capabilitySetLength != sizeof(CLIPRDR_GENERAL_CAPABILITY_SET))
|
||||
+ {
|
||||
+ WLog_ERR(TAG,
|
||||
+ "invalid capabilitySetLength %" PRIu16 " != %" PRIuz
|
||||
+ " (capabilitySetType=CB_CAPSTYPE_GENERAL)",
|
||||
+ capabilitySetLength, sizeof(CLIPRDR_GENERAL_CAPABILITY_SET));
|
||||
+ goto out;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ WLog_ERR(TAG, "unknown cliprdr capability set: %" PRIu16 "", capabilitySetType);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
cap_sets_size += capabilitySetLength;
|
||||
|
||||
- if (cap_sets_size > 0)
|
||||
- tmp = realloc(capabilities.capabilitySets, cap_sets_size);
|
||||
+ tmp = realloc(capabilities.capabilitySets, cap_sets_size);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
WLog_ERR(TAG, "capabilities.capabilitySets realloc failed!");
|
||||
@@ -546,7 +576,7 @@ static UINT cliprdr_server_receive_capabilities(CliprdrServerContext* context, w
|
||||
|
||||
capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET*)tmp;
|
||||
|
||||
- capSet = &(capabilities.capabilitySets[index]);
|
||||
+ capSet = (CLIPRDR_CAPABILITY_SET*)(((BYTE*)capabilities.capabilitySets) + cap_set_offset);
|
||||
|
||||
capSet->capabilitySetType = capabilitySetType;
|
||||
capSet->capabilitySetLength = capabilitySetLength;
|
||||
--
|
||||
2.52.0
|
||||
31
channels-rdpear-disable-ndr-pointer-aliasing.patch
Normal file
31
channels-rdpear-disable-ndr-pointer-aliasing.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From ae03a9ff981ce7be1ab09dba2cd319d54984f910 Mon Sep 17 00:00:00 2001
|
||||
From: David Fort <contact@hardening-consulting.com>
|
||||
Date: Wed, 6 May 2026 09:52:33 +0200
|
||||
Subject: [PATCH] Fix for GHSA-j9q5-7g8m-jc9v, disable NDR pointer aliasing
|
||||
|
||||
The usage of aliased pointers can be used to trigger a double free, or a type confusion
|
||||
(using the same memory location twice and pretend it's 2 different types of objects).
|
||||
As pointer aliasing is never seen in practice with RDPEAR, let's just return an error
|
||||
when we see an aliased pointer.
|
||||
---
|
||||
channels/rdpear/common/ndr.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/channels/rdpear/common/ndr.c b/channels/rdpear/common/ndr.c
|
||||
index 6e4b10aa8..20cc31c6e 100644
|
||||
--- a/channels/rdpear/common/ndr.c
|
||||
+++ b/channels/rdpear/common/ndr.c
|
||||
@@ -931,6 +931,11 @@ BOOL ndr_read_pointedMessageEx(NdrContext* context, wStream* s, ndr_refid ptrId,
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "aliased pointer aren't supported for now");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
|
||||
*target = ret;
|
||||
return TRUE;
|
||||
--
|
||||
2.54.0
|
||||
36
channels-rdpear-fix-ndr_read-checks.patch
Normal file
36
channels-rdpear-fix-ndr_read-checks.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From 668fcb49d4856fad28f685db54a572af2a284b50 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Sat, 10 Jan 2026 09:33:54 +0100
|
||||
Subject: [PATCH] [channels,rdpear] fix ndr_read checks
|
||||
|
||||
---
|
||||
channels/rdpear/common/ndr.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/channels/rdpear/common/ndr.c b/channels/rdpear/common/ndr.c
|
||||
index d318ed63c..d0bd6d959 100644
|
||||
--- a/channels/rdpear/common/ndr.c
|
||||
+++ b/channels/rdpear/common/ndr.c
|
||||
@@ -574,8 +574,10 @@ BOOL ndr_read_uconformant_array(NdrContext* context, wStream* s, const NdrArrayH
|
||||
WINPR_ASSERT(itemType);
|
||||
WINPR_ASSERT(vtarget);
|
||||
|
||||
- UINT32 count = 0;
|
||||
+ if (itemType->itemSize == 0)
|
||||
+ return FALSE;
|
||||
|
||||
+ UINT32 count = 0;
|
||||
if (!ndr_read_uint32(context, s, &count))
|
||||
return FALSE;
|
||||
|
||||
@@ -910,6 +912,8 @@ BOOL ndr_read_pointedMessageEx(NdrContext* context, wStream* s, ndr_refid ptrId,
|
||||
if (!ret)
|
||||
{
|
||||
size_t itemCount = ndr_hintsCount(descr, hints);
|
||||
+ if (itemCount == 0)
|
||||
+ return FALSE;
|
||||
ret = calloc(itemCount, descr->itemSize);
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
--
|
||||
2.54.0
|
||||
170
client-x11-fix-deadlock-on-output-expose.patch
Normal file
170
client-x11-fix-deadlock-on-output-expose.patch
Normal file
@ -0,0 +1,170 @@
|
||||
From 4c5a54419f0d6b62454acf2069ca5bf97f6952e7 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Tue, 5 May 2026 11:04:31 +0000
|
||||
Subject: [PATCH] [client,x11] fix deadlock on output expose
|
||||
|
||||
Backport of commit a278ff74117444c635c50ffa5084ecf517171f5a.
|
||||
|
||||
Adapted for 3.10.3: `WINPR_ATTR_NODISCARD` attribute removed
|
||||
(not available in 3.10.3), C99 `bool` replaced with `BOOL`,
|
||||
adjusted hunk offsets.
|
||||
|
||||
Made-with: Cursor
|
||||
---
|
||||
client/X11/xf_client.c | 3 ++
|
||||
client/X11/xf_event.c | 78 +++++++++++++++++++++++++-----------------
|
||||
client/X11/xf_event.h | 3 ++
|
||||
client/X11/xfreerdp.h | 3 ++
|
||||
4 files changed, 56 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c
|
||||
index 7ad30d6..08dc2ca 100644
|
||||
--- a/client/X11/xf_client.c
|
||||
+++ b/client/X11/xf_client.c
|
||||
@@ -514,6 +514,9 @@ static BOOL xf_process_x_events(freerdp* instance)
|
||||
xf_unlock_x11(xfc);
|
||||
if (!status)
|
||||
break;
|
||||
+ status = xf_event_update_screen(instance);
|
||||
+ if (!status)
|
||||
+ break;
|
||||
}
|
||||
|
||||
return status;
|
||||
diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c
|
||||
index a1fbb84..172fb68 100644
|
||||
--- a/client/X11/xf_event.c
|
||||
+++ b/client/X11/xf_event.c
|
||||
@@ -370,50 +370,30 @@ void xf_event_adjust_coordinates(xfContext* xfc, int* x, int* y)
|
||||
|
||||
static BOOL xf_event_Expose(xfContext* xfc, const XExposeEvent* event, BOOL app)
|
||||
{
|
||||
- int x = 0;
|
||||
- int y = 0;
|
||||
- int w = 0;
|
||||
- int h = 0;
|
||||
- rdpSettings* settings = NULL;
|
||||
-
|
||||
WINPR_ASSERT(xfc);
|
||||
WINPR_ASSERT(event);
|
||||
|
||||
- settings = xfc->common.context.settings;
|
||||
+ rdpSettings* settings = xfc->common.context.settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
if (!app && (freerdp_settings_get_bool(settings, FreeRDP_SmartSizing) ||
|
||||
freerdp_settings_get_bool(settings, FreeRDP_MultiTouchGestures)))
|
||||
{
|
||||
- x = 0;
|
||||
- y = 0;
|
||||
- w = freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth);
|
||||
- h = freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight);
|
||||
+ xfc->exposedArea.x = 0;
|
||||
+ xfc->exposedArea.y = 0;
|
||||
+ xfc->exposedArea.w = freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth);
|
||||
+ xfc->exposedArea.h = freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
- x = event->x;
|
||||
- y = event->y;
|
||||
- w = event->width;
|
||||
- h = event->height;
|
||||
+ xfc->exposedArea.x = event->x;
|
||||
+ xfc->exposedArea.y = event->y;
|
||||
+ xfc->exposedArea.w = event->width;
|
||||
+ xfc->exposedArea.h = event->height;
|
||||
}
|
||||
|
||||
- if (!app)
|
||||
- {
|
||||
- if (xfc->common.context.gdi->gfx)
|
||||
- {
|
||||
- xf_OutputExpose(xfc, x, y, w, h);
|
||||
- return TRUE;
|
||||
- }
|
||||
- xf_draw_screen(xfc, x, y, w, h);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
|
||||
- if (appWindow)
|
||||
- xf_UpdateWindowArea(xfc, appWindow, x, y, w, h);
|
||||
- xf_rail_return_window(appWindow, FALSE);
|
||||
- }
|
||||
+ xfc->exposedWindow = event->window;
|
||||
+ xfc->exposeRequested = true;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1372,3 +1352,39 @@ BOOL xf_generic_RawButtonEvent(xfContext* xfc, int button, BOOL app, BOOL down)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
+
|
||||
+BOOL xf_event_update_screen(freerdp* instance)
|
||||
+{
|
||||
+ WINPR_ASSERT(instance);
|
||||
+
|
||||
+ xfContext* xfc = (xfContext*)instance->context;
|
||||
+ WINPR_ASSERT(xfc);
|
||||
+
|
||||
+ rdpSettings* settings = xfc->common.context.settings;
|
||||
+ WINPR_ASSERT(settings);
|
||||
+
|
||||
+ if (!xfc->exposeRequested)
|
||||
+ return TRUE;
|
||||
+ xfc->exposeRequested = false;
|
||||
+
|
||||
+ if (!xfc->remote_app)
|
||||
+ {
|
||||
+ if (xfc->common.context.gdi->gfx)
|
||||
+ {
|
||||
+ xf_OutputExpose(xfc, xfc->exposedArea.x, xfc->exposedArea.y,
|
||||
+ xfc->exposedArea.w, xfc->exposedArea.h);
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ xf_draw_screen(xfc, xfc->exposedArea.x, xfc->exposedArea.y, xfc->exposedArea.w,
|
||||
+ xfc->exposedArea.h);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, xfc->exposedWindow);
|
||||
+ if (appWindow)
|
||||
+ xf_UpdateWindowArea(xfc, appWindow, xfc->exposedArea.x, xfc->exposedArea.y,
|
||||
+ xfc->exposedArea.w, xfc->exposedArea.h);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
diff --git a/client/X11/xf_event.h b/client/X11/xf_event.h
|
||||
index 2f4ab07..299d2d3 100644
|
||||
--- a/client/X11/xf_event.h
|
||||
+++ b/client/X11/xf_event.h
|
||||
@@ -31,6 +31,9 @@ BOOL xf_event_action_script_init(xfContext* xfc);
|
||||
void xf_event_action_script_free(xfContext* xfc);
|
||||
|
||||
BOOL xf_event_process(freerdp* instance, const XEvent* event);
|
||||
+
|
||||
+BOOL xf_event_update_screen(freerdp* instance);
|
||||
+
|
||||
void xf_event_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsigned int numArgs,
|
||||
...);
|
||||
|
||||
diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h
|
||||
index ba41553..677e3bc 100644
|
||||
--- a/client/X11/xfreerdp.h
|
||||
+++ b/client/X11/xfreerdp.h
|
||||
@@ -319,6 +319,9 @@ struct xf_context
|
||||
BOOL xi_event;
|
||||
HANDLE pipethread;
|
||||
wLog* log;
|
||||
+ bool exposeRequested;
|
||||
+ GDI_RGN exposedArea;
|
||||
+ Window exposedWindow;
|
||||
};
|
||||
|
||||
BOOL xf_create_window(xfContext* xfc);
|
||||
--
|
||||
2.54.0
|
||||
|
||||
413
client-x11-improve-rails-window-locking.patch
Normal file
413
client-x11-improve-rails-window-locking.patch
Normal file
@ -0,0 +1,413 @@
|
||||
From 24ef57b3085bfc353ab375ebba6a1c29d13929f1 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Tue, 5 May 2026 11:04:17 +0000
|
||||
Subject: [PATCH] [client,x11] improve rails window locking
|
||||
|
||||
Backport of commit 78fd7f580d5f9e6d9d582d82e5ea96003844fbdf.
|
||||
|
||||
Adapted for 3.10.3: `nullptr` replaced with `NULL`,
|
||||
`WINPR_ATTR_MALLOC` updated for renamed function,
|
||||
`WINPR_ATTR_UNUSED` removed from `xfAppWindowsLockFrom`/
|
||||
`UnlockFrom` signatures, `LogDynAndXSetTransientForHint`
|
||||
replaced with inline `XSetTransientForHint` + `WLog_WARN`,
|
||||
`xf_rail_add_window` parameter types `INT32` to `UINT32`,
|
||||
`WLog_PrintTextMessage` replaced with `WLog_PrintMessage`
|
||||
(not available in 3.10.3).
|
||||
|
||||
Made-with: Cursor
|
||||
---
|
||||
client/X11/xf_event.c | 3 +-
|
||||
client/X11/xf_graphics.c | 5 +--
|
||||
client/X11/xf_rail.c | 52 +++++++++++++----------------
|
||||
client/X11/xf_rail.h | 11 +++++--
|
||||
client/X11/xf_window.c | 70 ++++++++++++++++++++++++++++++++++++----
|
||||
client/X11/xf_window.h | 12 +++++--
|
||||
client/X11/xfreerdp.h | 4 +++
|
||||
7 files changed, 112 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c
|
||||
index b26ece0..f82ab94 100644
|
||||
--- a/client/X11/xf_event.c
|
||||
+++ b/client/X11/xf_event.c
|
||||
@@ -411,9 +411,8 @@ static BOOL xf_event_Expose(xfContext* xfc, const XExposeEvent* event, BOOL app)
|
||||
{
|
||||
xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
|
||||
if (appWindow)
|
||||
- {
|
||||
xf_UpdateWindowArea(xfc, appWindow, x, y, w, h);
|
||||
- }
|
||||
+ xf_rail_return_window(appWindow);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c
|
||||
index 5e68354..310f2a4 100644
|
||||
--- a/client/X11/xf_graphics.c
|
||||
+++ b/client/X11/xf_graphics.c
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "xf_graphics.h"
|
||||
#include "xf_event.h"
|
||||
+#include "xf_window.h"
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#define TAG CLIENT_TAG("x11")
|
||||
@@ -252,12 +253,12 @@ static Window xf_Pointer_get_window(xfContext* xfc)
|
||||
if (xfc->remote_app)
|
||||
{
|
||||
Window w = 0;
|
||||
- HashTable_Lock(xfc->railWindows);
|
||||
+ xf_AppWindowsLock(xfc);
|
||||
if (!xfc->appWindow)
|
||||
WLog_WARN(TAG, "xf_Pointer: Invalid appWindow");
|
||||
else
|
||||
w = xfc->appWindow->handle;
|
||||
- HashTable_Unlock(xfc->railWindows);
|
||||
+ xf_AppWindowsUnlock(xfc);
|
||||
return w;
|
||||
}
|
||||
else
|
||||
diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c
|
||||
index 2d79867..3353a8d 100644
|
||||
--- a/client/X11/xf_rail.c
|
||||
+++ b/client/X11/xf_rail.c
|
||||
@@ -109,9 +109,9 @@ void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
|
||||
|
||||
WINPR_ASSERT(appWindow->windowId <= UINT32_MAX);
|
||||
activate.windowId = (UINT32)appWindow->windowId;
|
||||
+ xf_rail_return_window(appWindow);
|
||||
activate.enabled = enabled;
|
||||
xfc->rail->ClientActivate(xfc->rail, &activate);
|
||||
- xf_rail_return_window(appWindow);
|
||||
}
|
||||
|
||||
BOOL xf_rail_send_client_system_command(xfContext* xfc, UINT64 windowId, UINT16 command)
|
||||
@@ -309,10 +309,12 @@ static void window_state_log_style_int(wLog* log, const WINDOW_STATE_ORDER* wind
|
||||
static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
|
||||
const WINDOW_STATE_ORDER* windowState)
|
||||
{
|
||||
+ BOOL rc = FALSE;
|
||||
+ xfAppWindow* appWindow = NULL;
|
||||
xfContext* xfc = (xfContext*)context;
|
||||
UINT32 fieldFlags = orderInfo->fieldFlags;
|
||||
BOOL position_or_size_updated = FALSE;
|
||||
- xfAppWindow* appWindow = xf_rail_get_window(xfc, orderInfo->windowId);
|
||||
+ appWindow = xf_rail_get_window(xfc, orderInfo->windowId);
|
||||
|
||||
if (fieldFlags & WINDOW_ORDER_STATE_NEW)
|
||||
{
|
||||
@@ -322,7 +324,7 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
||||
windowState->windowHeight, 0xFFFFFFFF);
|
||||
|
||||
if (!appWindow)
|
||||
- return FALSE;
|
||||
+ goto fail;
|
||||
|
||||
appWindow->dwStyle = windowState->style;
|
||||
appWindow->dwExStyle = windowState->extendedStyle;
|
||||
@@ -363,13 +365,13 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
||||
}
|
||||
|
||||
if (!appWindow->title)
|
||||
- return FALSE;
|
||||
+ goto fail;
|
||||
|
||||
xf_AppWindowInit(xfc, appWindow);
|
||||
}
|
||||
|
||||
if (!appWindow)
|
||||
- return FALSE;
|
||||
+ goto fail;
|
||||
|
||||
/* Keep track of any position/size update so that we can force a refresh of the window */
|
||||
if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
|
||||
@@ -441,14 +443,14 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
||||
if (!(title = _strdup("")))
|
||||
{
|
||||
WLog_ERR(TAG, "failed to duplicate empty window title string");
|
||||
- return FALSE;
|
||||
+ goto fail;
|
||||
}
|
||||
}
|
||||
else if (!(title = ConvertWCharNToUtf8Alloc(
|
||||
cnv.wc, windowState->titleInfo.length / sizeof(WCHAR), NULL)))
|
||||
{
|
||||
WLog_ERR(TAG, "failed to convert window title");
|
||||
- return FALSE;
|
||||
+ goto fail;
|
||||
}
|
||||
|
||||
free(appWindow->title);
|
||||
@@ -489,7 +491,7 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
||||
(RECTANGLE_16*)calloc(appWindow->numWindowRects, sizeof(RECTANGLE_16));
|
||||
|
||||
if (!appWindow->windowRects)
|
||||
- return FALSE;
|
||||
+ goto fail;
|
||||
|
||||
CopyMemory(appWindow->windowRects, windowState->windowRects,
|
||||
appWindow->numWindowRects * sizeof(RECTANGLE_16));
|
||||
@@ -518,7 +520,7 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
||||
(RECTANGLE_16*)calloc(appWindow->numVisibilityRects, sizeof(RECTANGLE_16));
|
||||
|
||||
if (!appWindow->visibilityRects)
|
||||
- return FALSE;
|
||||
+ goto fail;
|
||||
|
||||
CopyMemory(appWindow->visibilityRects, windowState->visibilityRects,
|
||||
appWindow->numVisibilityRects * sizeof(RECTANGLE_16));
|
||||
@@ -594,7 +596,10 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
||||
{
|
||||
xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects);
|
||||
}*/
|
||||
- return TRUE;
|
||||
+ rc = TRUE;
|
||||
+fail:
|
||||
+ xf_rail_return_window(appWindow);
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static BOOL xf_rail_window_delete(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo)
|
||||
@@ -1012,14 +1017,14 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context,
|
||||
x = localMoveSize->posX;
|
||||
y = localMoveSize->posY;
|
||||
/* FIXME: local keyboard moves not working */
|
||||
- return CHANNEL_RC_OK;
|
||||
+ break;
|
||||
|
||||
case RAIL_WMSZ_KEYSIZE:
|
||||
direction = _NET_WM_MOVERESIZE_SIZE_KEYBOARD;
|
||||
x = localMoveSize->posX;
|
||||
y = localMoveSize->posY;
|
||||
/* FIXME: local keyboard moves not working */
|
||||
- return CHANNEL_RC_OK;
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1196,13 +1201,16 @@ xfAppWindow* xf_rail_add_window(xfContext* xfc, UINT64 id, UINT32 x, UINT32 y, U
|
||||
appWindow->width = width;
|
||||
appWindow->height = height;
|
||||
|
||||
+ xf_AppWindowsLock(xfc);
|
||||
if (!xf_AppWindowCreate(xfc, appWindow))
|
||||
goto fail;
|
||||
+
|
||||
if (!HashTable_Insert(xfc->railWindows, &appWindow->windowId, (void*)appWindow))
|
||||
goto fail;
|
||||
return appWindow;
|
||||
fail:
|
||||
rail_window_free(appWindow);
|
||||
+ xf_AppWindowsUnlock(xfc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1217,26 +1225,10 @@ BOOL xf_rail_del_window(xfContext* xfc, UINT64 id)
|
||||
return HashTable_Remove(xfc->railWindows, &id);
|
||||
}
|
||||
|
||||
-xfAppWindow* xf_rail_get_window(xfContext* xfc, UINT64 id)
|
||||
-{
|
||||
- if (!xfc)
|
||||
- return NULL;
|
||||
-
|
||||
- if (!xfc->railWindows)
|
||||
- return NULL;
|
||||
-
|
||||
- HashTable_Lock(xfc->railWindows);
|
||||
- xfAppWindow* window = HashTable_GetItemValue(xfc->railWindows, &id);
|
||||
- if (!window)
|
||||
- HashTable_Unlock(xfc->railWindows);
|
||||
-
|
||||
- return window;
|
||||
-}
|
||||
-
|
||||
-void xf_rail_return_window(xfAppWindow* window)
|
||||
+void xf_rail_return_windowFrom(xfAppWindow* window, const char* file, const char* fkt, size_t line)
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
- HashTable_Unlock(window->xfc->railWindows);
|
||||
+ xfAppWindowsUnlockFrom(window->xfc, file, fkt, line);
|
||||
}
|
||||
diff --git a/client/X11/xf_rail.h b/client/X11/xf_rail.h
|
||||
index 8e8ed33..2b365b5 100644
|
||||
--- a/client/X11/xf_rail.h
|
||||
+++ b/client/X11/xf_rail.h
|
||||
@@ -38,9 +38,14 @@ void xf_rail_disable_remoteapp_mode(xfContext* xfc);
|
||||
xfAppWindow* xf_rail_add_window(xfContext* xfc, UINT64 id, UINT32 x, UINT32 y, UINT32 width,
|
||||
UINT32 height, UINT32 surfaceId);
|
||||
|
||||
-void xf_rail_return_window(xfAppWindow* window);
|
||||
-
|
||||
-xfAppWindow* xf_rail_get_window(xfContext* xfc, UINT64 id);
|
||||
+#define xf_rail_return_window(window) \
|
||||
+ xf_rail_return_windowFrom((window), __FILE__, __func__, __LINE__)
|
||||
+void xf_rail_return_windowFrom(xfAppWindow* window, const char* file, const char* fkt, size_t line);
|
||||
+
|
||||
+#define xf_rail_get_window(xfc, id) \
|
||||
+ xf_rail_get_windowFrom((xfc), (id), __FILE__, __func__, __LINE__)
|
||||
+xfAppWindow* xf_rail_get_windowFrom(xfContext* xfc, UINT64 id, const char* file, const char* fkt,
|
||||
+ size_t line);
|
||||
|
||||
BOOL xf_rail_del_window(xfContext* xfc, UINT64 id);
|
||||
|
||||
diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c
|
||||
index 801efbc..8d7bcd6 100644
|
||||
--- a/client/X11/xf_window.c
|
||||
+++ b/client/X11/xf_window.c
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include <winpr/assert.h>
|
||||
#include <winpr/thread.h>
|
||||
+#include <winpr/synch.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/string.h>
|
||||
|
||||
@@ -1404,7 +1405,31 @@ void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow)
|
||||
free(appWindow);
|
||||
}
|
||||
|
||||
-xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd)
|
||||
+static xfAppWindow* get_windowUnlocked(xfContext* xfc, UINT64 id)
|
||||
+{
|
||||
+ WINPR_ASSERT(xfc);
|
||||
+ return HashTable_GetItemValue(xfc->railWindows, &id);
|
||||
+}
|
||||
+
|
||||
+xfAppWindow* xf_rail_get_windowFrom(xfContext* xfc, UINT64 id, const char* file, const char* fkt,
|
||||
+ size_t line)
|
||||
+{
|
||||
+ if (!xfc)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (!xfc->railWindows)
|
||||
+ return NULL;
|
||||
+
|
||||
+ xfAppWindowsLockFrom(xfc, file, fkt, line);
|
||||
+ xfAppWindow* window = get_windowUnlocked(xfc, id);
|
||||
+ if (!window)
|
||||
+ xfAppWindowsUnlockFrom(xfc, file, fkt, line);
|
||||
+
|
||||
+ return window;
|
||||
+}
|
||||
+
|
||||
+xfAppWindow* xf_AppWindowFromX11WindowFrom(xfContext* xfc, Window wnd, const char* file,
|
||||
+ const char* fkt, size_t line)
|
||||
{
|
||||
ULONG_PTR* pKeys = NULL;
|
||||
|
||||
@@ -1412,29 +1437,28 @@ xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd)
|
||||
if (!xfc->railWindows)
|
||||
return NULL;
|
||||
|
||||
- HashTable_Lock(xfc->railWindows);
|
||||
+ xfAppWindowsLockFrom(xfc, file, fkt, line);
|
||||
size_t count = HashTable_GetKeys(xfc->railWindows, &pKeys);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
- xfAppWindow* appWindow = HashTable_GetItemValue(xfc->railWindows, (void*)pKeys[index]);
|
||||
+ xfAppWindow* appWindow = get_windowUnlocked(xfc, *(UINT64*)pKeys[index]);
|
||||
|
||||
if (!appWindow)
|
||||
{
|
||||
- HashTable_Unlock(xfc->railWindows);
|
||||
+ xfAppWindowsUnlockFrom(xfc, file, fkt, line);
|
||||
free(pKeys);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (appWindow->handle == wnd)
|
||||
{
|
||||
- HashTable_Unlock(xfc->railWindows);
|
||||
free(pKeys);
|
||||
return appWindow;
|
||||
}
|
||||
}
|
||||
|
||||
- HashTable_Unlock(xfc->railWindows);
|
||||
+ xfAppWindowsUnlockFrom(xfc, file, fkt, line);
|
||||
free(pKeys);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1556,3 +1580,37 @@ void xf_XSetTransientForHint(xfContext* xfc, xfAppWindow* window)
|
||||
}
|
||||
xf_rail_return_window(parent);
|
||||
}
|
||||
+
|
||||
+void xfAppWindowsLockFrom(xfContext* xfc, const char* file, const char* fkt, size_t line)
|
||||
+{
|
||||
+ WINPR_ASSERT(xfc);
|
||||
+
|
||||
+#if defined(WITH_VERBOSE_WINPR_ASSERT)
|
||||
+ const DWORD level = WLOG_TRACE;
|
||||
+ if (WLog_IsLevelActive(xfc->log, level))
|
||||
+ WLog_PrintMessage(xfc->log, WLOG_MESSAGE_TEXT, level, line, file, fkt, "[rails] locking [%s]", fkt);
|
||||
+#endif
|
||||
+
|
||||
+ HashTable_Lock(xfc->railWindows);
|
||||
+
|
||||
+#if defined(WITH_VERBOSE_WINPR_ASSERT)
|
||||
+ WINPR_ASSERT(!xfc->isRailWindowsLocked);
|
||||
+ xfc->isRailWindowsLocked = TRUE;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void xfAppWindowsUnlockFrom(xfContext* xfc, const char* file, const char* fkt, size_t line)
|
||||
+{
|
||||
+ WINPR_ASSERT(xfc);
|
||||
+
|
||||
+#if defined(WITH_VERBOSE_WINPR_ASSERT)
|
||||
+ const DWORD level = WLOG_TRACE;
|
||||
+ if (WLog_IsLevelActive(xfc->log, level))
|
||||
+ WLog_PrintMessage(xfc->log, WLOG_MESSAGE_TEXT, level, line, file, fkt, "[rails] unocking [%s]", fkt);
|
||||
+
|
||||
+ WINPR_ASSERT(xfc->isRailWindowsLocked);
|
||||
+ xfc->isRailWindowsLocked = FALSE;
|
||||
+#endif
|
||||
+
|
||||
+ HashTable_Unlock(xfc->railWindows);
|
||||
+}
|
||||
diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h
|
||||
index 2384d61..25eedb3 100644
|
||||
--- a/client/X11/xf_window.h
|
||||
+++ b/client/X11/xf_window.h
|
||||
@@ -202,8 +202,16 @@ void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow, int maxWidth
|
||||
int maxTrackWidth, int maxTrackHeight);
|
||||
void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, int direction, int x, int y);
|
||||
void xf_EndLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow);
|
||||
-xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd);
|
||||
-void xf_rail_return_window(xfAppWindow* window);
|
||||
+#define xf_AppWindowFromX11Window(xfc, wnd) \
|
||||
+ xf_AppWindowFromX11WindowFrom((xfc), (wnd), __FILE__, __func__, __LINE__)
|
||||
+xfAppWindow* xf_AppWindowFromX11WindowFrom(xfContext* xfc, Window wnd, const char* file,
|
||||
+ const char* fkt, size_t line);
|
||||
+
|
||||
+#define xf_AppWindowsLock(xfc) xfAppWindowsLockFrom((xfc), __FILE__, __func__, __LINE__)
|
||||
+void xfAppWindowsLockFrom(xfContext* xfc, const char* file, const char* fkt, size_t line);
|
||||
+
|
||||
+#define xf_AppWindowsUnlock(xfc) xfAppWindowsUnlockFrom((xfc), __FILE__, __func__, __LINE__)
|
||||
+void xfAppWindowsUnlockFrom(xfContext* xfc, const char* file, const char* fkt, size_t line);
|
||||
|
||||
const char* window_styles_to_string(UINT32 style, char* buffer, size_t length);
|
||||
const char* window_styles_ex_to_string(UINT32 styleEx, char* buffer, size_t length);
|
||||
diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h
|
||||
index 000ba56..ba41553 100644
|
||||
--- a/client/X11/xfreerdp.h
|
||||
+++ b/client/X11/xfreerdp.h
|
||||
@@ -290,6 +290,10 @@ struct xf_context
|
||||
wHashTable* railWindows;
|
||||
xfRailIconCache* railIconCache;
|
||||
|
||||
+#if defined(WITH_VERBOSE_WINPR_ASSERT)
|
||||
+ BOOL isRailWindowsLocked;
|
||||
+#endif
|
||||
+
|
||||
BOOL xkbAvailable;
|
||||
BOOL xrenderAvailable;
|
||||
|
||||
--
|
||||
2.54.0
|
||||
|
||||
439
client-x11-lock-appwindow.patch
Normal file
439
client-x11-lock-appwindow.patch
Normal file
@ -0,0 +1,439 @@
|
||||
From 87ef0851132df9b00380f3cfe9d63272a85d7c49 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Tue, 5 May 2026 11:03:44 +0000
|
||||
Subject: [PATCH] [client,x11] lock appWindow
|
||||
|
||||
Backport of commit 1994e9844212a6dfe0ff12309fef520e888986b5.
|
||||
|
||||
Adapted for 3.10.3: `xf_generic_MotionNotify_` renamed to
|
||||
`xf_generic_MotionNotify`, `xf_generic_ButtonEvent_` to
|
||||
`xf_generic_ButtonEvent`, `WINPR_ATTR_MALLOC` attribute removed
|
||||
(not available in 3.10.3), adjusted hunk offsets.
|
||||
|
||||
Made-with: Cursor
|
||||
---
|
||||
client/X11/xf_event.c | 47 ++++++++++++++++++----------
|
||||
client/X11/xf_graphics.c | 10 +++---
|
||||
client/X11/xf_rail.c | 67 ++++++++++++++++++++++++++--------------
|
||||
client/X11/xf_rail.h | 3 ++
|
||||
client/X11/xf_window.c | 8 ++++-
|
||||
client/X11/xf_window.h | 1 +
|
||||
6 files changed, 92 insertions(+), 44 deletions(-)
|
||||
|
||||
diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c
|
||||
index 0fce625..b26ece0 100644
|
||||
--- a/client/X11/xf_event.c
|
||||
+++ b/client/X11/xf_event.c
|
||||
@@ -442,7 +442,9 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win
|
||||
if (app)
|
||||
{
|
||||
/* make sure window exists */
|
||||
- if (!xf_AppWindowFromX11Window(xfc, window))
|
||||
+ xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, window);
|
||||
+ xf_rail_return_window(appWindow);
|
||||
+ if (!appWindow)
|
||||
return TRUE;
|
||||
|
||||
/* Translate to desktop coordinates */
|
||||
@@ -536,7 +538,9 @@ BOOL xf_generic_ButtonEvent(xfContext* xfc, int x, int y, int button, Window win
|
||||
if (app)
|
||||
{
|
||||
/* make sure window exists */
|
||||
- if (!xf_AppWindowFromX11Window(xfc, window))
|
||||
+ xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, window);
|
||||
+ xf_rail_return_window(appWindow);
|
||||
+ if (!appWindow)
|
||||
return TRUE;
|
||||
|
||||
/* Translate to desktop coordinates */
|
||||
@@ -694,6 +698,7 @@ static BOOL xf_event_FocusIn(xfContext* xfc, const XFocusInEvent* event, BOOL ap
|
||||
*/
|
||||
if (appWindow)
|
||||
xf_rail_adjust_position(xfc, appWindow);
|
||||
+ xf_rail_return_window(appWindow);
|
||||
}
|
||||
|
||||
xf_keyboard_focus_in(xfc);
|
||||
@@ -734,12 +739,13 @@ static BOOL xf_event_ClientMessage(xfContext* xfc, const XClientMessageEvent* ev
|
||||
{
|
||||
if (app)
|
||||
{
|
||||
+ BOOL rc = TRUE;
|
||||
xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
|
||||
|
||||
if (appWindow)
|
||||
- return xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_CLOSE);
|
||||
-
|
||||
- return TRUE;
|
||||
+ rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_CLOSE);
|
||||
+ xf_rail_return_window(appWindow);
|
||||
+ return rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -772,6 +778,7 @@ static BOOL xf_event_EnterNotify(xfContext* xfc, const XEnterWindowEvent* event,
|
||||
|
||||
/* keep track of which window has focus so that we can apply pointer updates */
|
||||
xfc->appWindow = appWindow;
|
||||
+ xf_rail_return_window(appWindow);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -793,6 +800,7 @@ static BOOL xf_event_LeaveNotify(xfContext* xfc, const XLeaveWindowEvent* event,
|
||||
/* keep track of which window has focus so that we can apply pointer updates */
|
||||
if (xfc->appWindow == appWindow)
|
||||
xfc->appWindow = NULL;
|
||||
+ xf_rail_return_window(appWindow);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -893,6 +901,7 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, const XConfigureEvent* even
|
||||
xf_rail_adjust_position(xfc, appWindow);
|
||||
}
|
||||
}
|
||||
+ xf_rail_return_window(appWindow);
|
||||
}
|
||||
return xf_pointer_update_scale(xfc);
|
||||
}
|
||||
@@ -916,6 +925,7 @@ static BOOL xf_event_MapNotify(xfContext* xfc, const XMapEvent* event, BOOL app)
|
||||
// xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
|
||||
appWindow->is_mapped = TRUE;
|
||||
}
|
||||
+ xf_rail_return_window(appWindow);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -930,13 +940,14 @@ static BOOL xf_event_UnmapNotify(xfContext* xfc, const XUnmapEvent* event, BOOL
|
||||
xf_keyboard_release_all_keypress(xfc);
|
||||
|
||||
if (!app)
|
||||
- gdi_send_suppress_output(xfc->common.context.gdi, TRUE);
|
||||
- else
|
||||
+ return gdi_send_suppress_output(xfc->common.context.gdi, TRUE);
|
||||
+
|
||||
{
|
||||
xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
|
||||
|
||||
if (appWindow)
|
||||
appWindow->is_mapped = FALSE;
|
||||
+ xf_rail_return_window(appWindow);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -944,6 +955,7 @@ static BOOL xf_event_UnmapNotify(xfContext* xfc, const XUnmapEvent* event, BOOL
|
||||
|
||||
static BOOL xf_event_PropertyNotify(xfContext* xfc, const XPropertyEvent* event, BOOL app)
|
||||
{
|
||||
+ BOOL rc = TRUE;
|
||||
WINPR_ASSERT(xfc);
|
||||
WINPR_ASSERT(event);
|
||||
|
||||
@@ -968,7 +980,7 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, const XPropertyEvent* event,
|
||||
appWindow = xf_AppWindowFromX11Window(xfc, event->window);
|
||||
|
||||
if (!appWindow)
|
||||
- return TRUE;
|
||||
+ goto fail;
|
||||
}
|
||||
|
||||
if (event->atom == xfc->_NET_WM_STATE)
|
||||
@@ -1040,8 +1052,7 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, const XPropertyEvent* event,
|
||||
if (appWindow->rail_state != WINDOW_SHOW_MAXIMIZED)
|
||||
{
|
||||
appWindow->rail_state = WINDOW_SHOW_MAXIMIZED;
|
||||
- return xf_rail_send_client_system_command(xfc, appWindow->windowId,
|
||||
- SC_MAXIMIZE);
|
||||
+ rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MAXIMIZE);
|
||||
}
|
||||
}
|
||||
else if (appWindow->minimized)
|
||||
@@ -1049,8 +1060,7 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, const XPropertyEvent* event,
|
||||
if (appWindow->rail_state != WINDOW_SHOW_MINIMIZED)
|
||||
{
|
||||
appWindow->rail_state = WINDOW_SHOW_MINIMIZED;
|
||||
- return xf_rail_send_client_system_command(xfc, appWindow->windowId,
|
||||
- SC_MINIMIZE);
|
||||
+ rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MINIMIZE);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1058,15 +1068,18 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, const XPropertyEvent* event,
|
||||
if (appWindow->rail_state != WINDOW_SHOW && appWindow->rail_state != WINDOW_HIDE)
|
||||
{
|
||||
appWindow->rail_state = WINDOW_SHOW;
|
||||
- return xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
|
||||
+ rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (minimizedChanged)
|
||||
- gdi_send_suppress_output(xfc->common.context.gdi, minimized);
|
||||
+ rc = gdi_send_suppress_output(xfc->common.context.gdi, minimized);
|
||||
+
|
||||
+ fail:
|
||||
+ xf_rail_return_window(appWindow);
|
||||
}
|
||||
|
||||
- return TRUE;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow, const XEvent* event)
|
||||
@@ -1182,7 +1195,9 @@ BOOL xf_event_process(freerdp* instance, const XEvent* event)
|
||||
/* Update "current" window for cursor change orders */
|
||||
xfc->appWindow = appWindow;
|
||||
|
||||
- if (xf_event_suppress_events(xfc, appWindow, event))
|
||||
+ const BOOL rc = xf_event_suppress_events(xfc, appWindow, event);
|
||||
+ xf_rail_return_window(appWindow);
|
||||
+ if (rc)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c
|
||||
index a6950ad..5e68354 100644
|
||||
--- a/client/X11/xf_graphics.c
|
||||
+++ b/client/X11/xf_graphics.c
|
||||
@@ -251,12 +251,14 @@ static Window xf_Pointer_get_window(xfContext* xfc)
|
||||
}
|
||||
if (xfc->remote_app)
|
||||
{
|
||||
+ Window w = 0;
|
||||
+ HashTable_Lock(xfc->railWindows);
|
||||
if (!xfc->appWindow)
|
||||
- {
|
||||
WLog_WARN(TAG, "xf_Pointer: Invalid appWindow");
|
||||
- return 0;
|
||||
- }
|
||||
- return xfc->appWindow->handle;
|
||||
+ else
|
||||
+ w = xfc->appWindow->handle;
|
||||
+ HashTable_Unlock(xfc->railWindows);
|
||||
+ return w;
|
||||
}
|
||||
else
|
||||
{
|
||||
diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c
|
||||
index f931b50..2d79867 100644
|
||||
--- a/client/X11/xf_rail.c
|
||||
+++ b/client/X11/xf_rail.c
|
||||
@@ -111,6 +111,7 @@ void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
|
||||
activate.windowId = (UINT32)appWindow->windowId;
|
||||
activate.enabled = enabled;
|
||||
xfc->rail->ClientActivate(xfc->rail, &activate);
|
||||
+ xf_rail_return_window(appWindow);
|
||||
}
|
||||
|
||||
BOOL xf_rail_send_client_system_command(xfContext* xfc, UINT64 windowId, UINT16 command)
|
||||
@@ -255,6 +256,7 @@ BOOL xf_rail_paint_surface(xfContext* xfc, UINT64 windowId, const RECTANGLE_16*
|
||||
updateRect.right - updateRect.left, updateRect.bottom - updateRect.top);
|
||||
}
|
||||
region16_uninit(&windowInvalidRegion);
|
||||
+ xf_rail_return_window(appWindow);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -729,61 +731,65 @@ static void xf_rail_set_window_icon(xfContext* xfc, xfAppWindow* railWindow, xfR
|
||||
static BOOL xf_rail_window_icon(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
|
||||
const WINDOW_ICON_ORDER* windowIcon)
|
||||
{
|
||||
+ BOOL rc = FALSE;
|
||||
xfContext* xfc = (xfContext*)context;
|
||||
- xfAppWindow* railWindow = NULL;
|
||||
- xfRailIcon* icon = NULL;
|
||||
BOOL replaceIcon = 0;
|
||||
- railWindow = xf_rail_get_window(xfc, orderInfo->windowId);
|
||||
+ xfAppWindow* railWindow = xf_rail_get_window(xfc, orderInfo->windowId);
|
||||
|
||||
if (!railWindow)
|
||||
return TRUE;
|
||||
|
||||
- icon = RailIconCache_Lookup(xfc->railIconCache, windowIcon->iconInfo->cacheId,
|
||||
+ xfRailIcon* icon = RailIconCache_Lookup(xfc->railIconCache, windowIcon->iconInfo->cacheId,
|
||||
windowIcon->iconInfo->cacheEntry);
|
||||
|
||||
if (!icon)
|
||||
{
|
||||
WLog_WARN(TAG, "failed to get icon from cache %02X:%04X", windowIcon->iconInfo->cacheId,
|
||||
windowIcon->iconInfo->cacheEntry);
|
||||
- return FALSE;
|
||||
}
|
||||
-
|
||||
- if (!convert_rail_icon(windowIcon->iconInfo, icon))
|
||||
+ else if (!convert_rail_icon(windowIcon->iconInfo, icon))
|
||||
{
|
||||
WLog_WARN(TAG, "failed to convert icon for window %08X", orderInfo->windowId);
|
||||
- return FALSE;
|
||||
}
|
||||
-
|
||||
- replaceIcon = !!(orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW);
|
||||
- xf_rail_set_window_icon(xfc, railWindow, icon, replaceIcon);
|
||||
- return TRUE;
|
||||
+ else
|
||||
+ {
|
||||
+ replaceIcon = !!(orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW);
|
||||
+ xf_rail_set_window_icon(xfc, railWindow, icon, replaceIcon);
|
||||
+ rc = TRUE;
|
||||
+ }
|
||||
+ xf_rail_return_window(railWindow);
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static BOOL xf_rail_window_cached_icon(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
|
||||
const WINDOW_CACHED_ICON_ORDER* windowCachedIcon)
|
||||
{
|
||||
+ BOOL rc = FALSE;
|
||||
xfContext* xfc = (xfContext*)context;
|
||||
- xfAppWindow* railWindow = NULL;
|
||||
- xfRailIcon* icon = NULL;
|
||||
+ WINPR_ASSERT(orderInfo);
|
||||
+
|
||||
BOOL replaceIcon = 0;
|
||||
- railWindow = xf_rail_get_window(xfc, orderInfo->windowId);
|
||||
+ xfAppWindow* railWindow = xf_rail_get_window(xfc, orderInfo->windowId);
|
||||
|
||||
if (!railWindow)
|
||||
return TRUE;
|
||||
|
||||
- icon = RailIconCache_Lookup(xfc->railIconCache, windowCachedIcon->cachedIcon.cacheId,
|
||||
+ xfRailIcon* icon = RailIconCache_Lookup(xfc->railIconCache, windowCachedIcon->cachedIcon.cacheId,
|
||||
windowCachedIcon->cachedIcon.cacheEntry);
|
||||
|
||||
if (!icon)
|
||||
{
|
||||
WLog_WARN(TAG, "failed to get icon from cache %02X:%04X",
|
||||
windowCachedIcon->cachedIcon.cacheId, windowCachedIcon->cachedIcon.cacheEntry);
|
||||
- return FALSE;
|
||||
}
|
||||
-
|
||||
- replaceIcon = !!(orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW);
|
||||
- xf_rail_set_window_icon(xfc, railWindow, icon, replaceIcon);
|
||||
- return TRUE;
|
||||
+ else
|
||||
+ {
|
||||
+ replaceIcon = !!(orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW);
|
||||
+ xf_rail_set_window_icon(xfc, railWindow, icon, replaceIcon);
|
||||
+ rc = TRUE;
|
||||
+ }
|
||||
+ xf_rail_return_window(railWindow);
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static BOOL xf_rail_notify_icon_common(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
|
||||
@@ -1023,6 +1029,7 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context,
|
||||
else
|
||||
xf_EndLocalMoveSize(xfc, appWindow);
|
||||
|
||||
+ xf_rail_return_window(appWindow);
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
@@ -1044,6 +1051,7 @@ static UINT xf_rail_server_min_max_info(RailClientContext* context,
|
||||
minMaxInfo->minTrackHeight, minMaxInfo->maxTrackWidth,
|
||||
minMaxInfo->maxTrackHeight);
|
||||
}
|
||||
+ xf_rail_return_window(appWindow);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
@@ -1215,7 +1223,20 @@ xfAppWindow* xf_rail_get_window(xfContext* xfc, UINT64 id)
|
||||
return NULL;
|
||||
|
||||
if (!xfc->railWindows)
|
||||
- return FALSE;
|
||||
+ return NULL;
|
||||
+
|
||||
+ HashTable_Lock(xfc->railWindows);
|
||||
+ xfAppWindow* window = HashTable_GetItemValue(xfc->railWindows, &id);
|
||||
+ if (!window)
|
||||
+ HashTable_Unlock(xfc->railWindows);
|
||||
+
|
||||
+ return window;
|
||||
+}
|
||||
+
|
||||
+void xf_rail_return_window(xfAppWindow* window)
|
||||
+{
|
||||
+ if (!window)
|
||||
+ return;
|
||||
|
||||
- return HashTable_GetItemValue(xfc->railWindows, &id);
|
||||
+ HashTable_Unlock(window->xfc->railWindows);
|
||||
}
|
||||
diff --git a/client/X11/xf_rail.h b/client/X11/xf_rail.h
|
||||
index 9cd54f0..8e8ed33 100644
|
||||
--- a/client/X11/xf_rail.h
|
||||
+++ b/client/X11/xf_rail.h
|
||||
@@ -37,6 +37,9 @@ void xf_rail_disable_remoteapp_mode(xfContext* xfc);
|
||||
|
||||
xfAppWindow* xf_rail_add_window(xfContext* xfc, UINT64 id, UINT32 x, UINT32 y, UINT32 width,
|
||||
UINT32 height, UINT32 surfaceId);
|
||||
+
|
||||
+void xf_rail_return_window(xfAppWindow* window);
|
||||
+
|
||||
xfAppWindow* xf_rail_get_window(xfContext* xfc, UINT64 id);
|
||||
|
||||
BOOL xf_rail_del_window(xfContext* xfc, UINT64 id);
|
||||
diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c
|
||||
index cf3d8bc..801efbc 100644
|
||||
--- a/client/X11/xf_window.c
|
||||
+++ b/client/X11/xf_window.c
|
||||
@@ -1412,25 +1412,29 @@ xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd)
|
||||
if (!xfc->railWindows)
|
||||
return NULL;
|
||||
|
||||
+ HashTable_Lock(xfc->railWindows);
|
||||
size_t count = HashTable_GetKeys(xfc->railWindows, &pKeys);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
- xfAppWindow* appWindow = xf_rail_get_window(xfc, *(UINT64*)pKeys[index]);
|
||||
+ xfAppWindow* appWindow = HashTable_GetItemValue(xfc->railWindows, (void*)pKeys[index]);
|
||||
|
||||
if (!appWindow)
|
||||
{
|
||||
+ HashTable_Unlock(xfc->railWindows);
|
||||
free(pKeys);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (appWindow->handle == wnd)
|
||||
{
|
||||
+ HashTable_Unlock(xfc->railWindows);
|
||||
free(pKeys);
|
||||
return appWindow;
|
||||
}
|
||||
}
|
||||
|
||||
+ HashTable_Unlock(xfc->railWindows);
|
||||
free(pKeys);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1509,6 +1513,7 @@ UINT xf_AppUpdateWindowFromSurface(xfContext* xfc, gdiGfxSurface* surface)
|
||||
|
||||
rc = CHANNEL_RC_OK;
|
||||
fail:
|
||||
+ xf_rail_return_window(appWindow);
|
||||
XFlush(xfc->display);
|
||||
xf_unlock_x11(xfc);
|
||||
return rc;
|
||||
@@ -1549,4 +1554,5 @@ void xf_XSetTransientForHint(xfContext* xfc, xfAppWindow* window)
|
||||
WLog_WARN(TAG, "XSetTransientForHint [%d]{%s}", rc,
|
||||
x11_error_to_string(xfc, rc, buffer, sizeof(buffer)));
|
||||
}
|
||||
+ xf_rail_return_window(parent);
|
||||
}
|
||||
diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h
|
||||
index efbc67d..2384d61 100644
|
||||
--- a/client/X11/xf_window.h
|
||||
+++ b/client/X11/xf_window.h
|
||||
@@ -203,6 +203,7 @@ void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow, int maxWidth
|
||||
void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, int direction, int x, int y);
|
||||
void xf_EndLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow);
|
||||
xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd);
|
||||
+void xf_rail_return_window(xfAppWindow* window);
|
||||
|
||||
const char* window_styles_to_string(UINT32 style, char* buffer, size_t length);
|
||||
const char* window_styles_ex_to_string(UINT32 styleEx, char* buffer, size_t length);
|
||||
--
|
||||
2.54.0
|
||||
|
||||
446
client-x11-refactor-locking.patch
Normal file
446
client-x11-refactor-locking.patch
Normal file
@ -0,0 +1,446 @@
|
||||
From aaa9a2609069494e89b166417ad47570d205c3bc Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Tue, 5 May 2026 11:04:31 +0000
|
||||
Subject: [PATCH] [client,x11] refactor locking
|
||||
|
||||
Backport of commit 4ff57b68c2960fa414d03c78ff0e0660be1cc5bd.
|
||||
|
||||
Adapted for 3.10.3: `LogDynAndXSetClipMask`/`LogDynAndXSync`
|
||||
replaced with direct `XSetClipMask`/`XSync` calls,
|
||||
`LogDynAndXPutImage`/`LogDynAndXFlush` replaced with direct
|
||||
`XPutImage`/`XFlush` calls, adjusted hunk offsets.
|
||||
|
||||
Made-with: Cursor
|
||||
---
|
||||
client/X11/xf_event.c | 24 ++++++++++++------------
|
||||
client/X11/xf_gfx.c | 4 ++--
|
||||
client/X11/xf_rail.c | 37 ++++++++++++++++++++++---------------
|
||||
client/X11/xf_rail.h | 17 +++++++++--------
|
||||
client/X11/xf_window.c | 27 ++++++++++++++-------------
|
||||
5 files changed, 59 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c
|
||||
index f82ab94..a1fbb84 100644
|
||||
--- a/client/X11/xf_event.c
|
||||
+++ b/client/X11/xf_event.c
|
||||
@@ -412,7 +412,7 @@ static BOOL xf_event_Expose(xfContext* xfc, const XExposeEvent* event, BOOL app)
|
||||
xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
|
||||
if (appWindow)
|
||||
xf_UpdateWindowArea(xfc, appWindow, x, y, w, h);
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -442,7 +442,7 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win
|
||||
{
|
||||
/* make sure window exists */
|
||||
xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, window);
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
if (!appWindow)
|
||||
return TRUE;
|
||||
|
||||
@@ -538,7 +538,7 @@ BOOL xf_generic_ButtonEvent(xfContext* xfc, int x, int y, int button, Window win
|
||||
{
|
||||
/* make sure window exists */
|
||||
xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, window);
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
if (!appWindow)
|
||||
return TRUE;
|
||||
|
||||
@@ -697,7 +697,7 @@ static BOOL xf_event_FocusIn(xfContext* xfc, const XFocusInEvent* event, BOOL ap
|
||||
*/
|
||||
if (appWindow)
|
||||
xf_rail_adjust_position(xfc, appWindow);
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
}
|
||||
|
||||
xf_keyboard_focus_in(xfc);
|
||||
@@ -743,7 +743,7 @@ static BOOL xf_event_ClientMessage(xfContext* xfc, const XClientMessageEvent* ev
|
||||
|
||||
if (appWindow)
|
||||
rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_CLOSE);
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
return rc;
|
||||
}
|
||||
else
|
||||
@@ -777,7 +777,7 @@ static BOOL xf_event_EnterNotify(xfContext* xfc, const XEnterWindowEvent* event,
|
||||
|
||||
/* keep track of which window has focus so that we can apply pointer updates */
|
||||
xfc->appWindow = appWindow;
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -799,7 +799,7 @@ static BOOL xf_event_LeaveNotify(xfContext* xfc, const XLeaveWindowEvent* event,
|
||||
/* keep track of which window has focus so that we can apply pointer updates */
|
||||
if (xfc->appWindow == appWindow)
|
||||
xfc->appWindow = NULL;
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -900,7 +900,7 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, const XConfigureEvent* even
|
||||
xf_rail_adjust_position(xfc, appWindow);
|
||||
}
|
||||
}
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
}
|
||||
return xf_pointer_update_scale(xfc);
|
||||
}
|
||||
@@ -924,7 +924,7 @@ static BOOL xf_event_MapNotify(xfContext* xfc, const XMapEvent* event, BOOL app)
|
||||
// xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
|
||||
appWindow->is_mapped = TRUE;
|
||||
}
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -946,7 +946,7 @@ static BOOL xf_event_UnmapNotify(xfContext* xfc, const XUnmapEvent* event, BOOL
|
||||
|
||||
if (appWindow)
|
||||
appWindow->is_mapped = FALSE;
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -1075,7 +1075,7 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, const XPropertyEvent* event,
|
||||
rc = gdi_send_suppress_output(xfc->common.context.gdi, minimized);
|
||||
|
||||
fail:
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -1195,7 +1195,7 @@ BOOL xf_event_process(freerdp* instance, const XEvent* event)
|
||||
xfc->appWindow = appWindow;
|
||||
|
||||
const BOOL rc = xf_event_suppress_events(xfc, appWindow, event);
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
if (rc)
|
||||
return TRUE;
|
||||
}
|
||||
diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c
|
||||
index 48a2755..b748cf4 100644
|
||||
--- a/client/X11/xf_gfx.c
|
||||
+++ b/client/X11/xf_gfx.c
|
||||
@@ -66,6 +66,7 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
|
||||
if (!(rects = region16_rects(&surface->gdi.invalidRegion, &nbRects)))
|
||||
return CHANNEL_RC_OK;
|
||||
|
||||
+ xf_lock_x11(xfc);
|
||||
for (UINT32 x = 0; x < nbRects; x++)
|
||||
{
|
||||
const RECTANGLE_16* rect = &rects[x];
|
||||
@@ -90,9 +91,7 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
|
||||
{
|
||||
XPutImage(xfc->display, xfc->primary, xfc->gc, surface->image, nXSrc, nYSrc, nXDst,
|
||||
nYDst, dwidth, dheight);
|
||||
- xf_lock_x11(xfc);
|
||||
xf_rail_paint_surface(xfc, surface->gdi.windowId, rect);
|
||||
- xf_unlock_x11(xfc);
|
||||
}
|
||||
else
|
||||
#ifdef WITH_XRENDER
|
||||
@@ -116,6 +115,7 @@ fail:
|
||||
region16_clear(&surface->gdi.invalidRegion);
|
||||
XSetClipMask(xfc->display, xfc->gc, None);
|
||||
XSync(xfc->display, False);
|
||||
+ xf_unlock_x11(xfc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c
|
||||
index 3353a8d..5322859 100644
|
||||
--- a/client/X11/xf_rail.c
|
||||
+++ b/client/X11/xf_rail.c
|
||||
@@ -109,7 +109,7 @@ void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
|
||||
|
||||
WINPR_ASSERT(appWindow->windowId <= UINT32_MAX);
|
||||
activate.windowId = (UINT32)appWindow->windowId;
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
activate.enabled = enabled;
|
||||
xfc->rail->ClientActivate(xfc->rail, &activate);
|
||||
}
|
||||
@@ -227,7 +227,7 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow)
|
||||
|
||||
BOOL xf_rail_paint_surface(xfContext* xfc, UINT64 windowId, const RECTANGLE_16* rect)
|
||||
{
|
||||
- xfAppWindow* appWindow = xf_rail_get_window(xfc, windowId);
|
||||
+ xfAppWindow* appWindow = xf_rail_get_window(xfc, windowId, FALSE);
|
||||
|
||||
WINPR_ASSERT(rect);
|
||||
|
||||
@@ -256,7 +256,7 @@ BOOL xf_rail_paint_surface(xfContext* xfc, UINT64 windowId, const RECTANGLE_16*
|
||||
updateRect.right - updateRect.left, updateRect.bottom - updateRect.top);
|
||||
}
|
||||
region16_uninit(&windowInvalidRegion);
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
||||
xfContext* xfc = (xfContext*)context;
|
||||
UINT32 fieldFlags = orderInfo->fieldFlags;
|
||||
BOOL position_or_size_updated = FALSE;
|
||||
- appWindow = xf_rail_get_window(xfc, orderInfo->windowId);
|
||||
+ appWindow = xf_rail_get_window(xfc, orderInfo->windowId, FALSE);
|
||||
|
||||
if (fieldFlags & WINDOW_ORDER_STATE_NEW)
|
||||
{
|
||||
@@ -598,7 +598,7 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO*
|
||||
}*/
|
||||
rc = TRUE;
|
||||
fail:
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -739,7 +739,7 @@ static BOOL xf_rail_window_icon(rdpContext* context, const WINDOW_ORDER_INFO* or
|
||||
BOOL rc = FALSE;
|
||||
xfContext* xfc = (xfContext*)context;
|
||||
BOOL replaceIcon = 0;
|
||||
- xfAppWindow* railWindow = xf_rail_get_window(xfc, orderInfo->windowId);
|
||||
+ xfAppWindow* railWindow = xf_rail_get_window(xfc, orderInfo->windowId, FALSE);
|
||||
|
||||
if (!railWindow)
|
||||
return TRUE;
|
||||
@@ -762,7 +762,7 @@ static BOOL xf_rail_window_icon(rdpContext* context, const WINDOW_ORDER_INFO* or
|
||||
xf_rail_set_window_icon(xfc, railWindow, icon, replaceIcon);
|
||||
rc = TRUE;
|
||||
}
|
||||
- xf_rail_return_window(railWindow);
|
||||
+ xf_rail_return_window(railWindow, FALSE);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -774,7 +774,7 @@ static BOOL xf_rail_window_cached_icon(rdpContext* context, const WINDOW_ORDER_I
|
||||
WINPR_ASSERT(orderInfo);
|
||||
|
||||
BOOL replaceIcon = 0;
|
||||
- xfAppWindow* railWindow = xf_rail_get_window(xfc, orderInfo->windowId);
|
||||
+ xfAppWindow* railWindow = xf_rail_get_window(xfc, orderInfo->windowId, FALSE);
|
||||
|
||||
if (!railWindow)
|
||||
return TRUE;
|
||||
@@ -793,7 +793,7 @@ static BOOL xf_rail_window_cached_icon(rdpContext* context, const WINDOW_ORDER_I
|
||||
xf_rail_set_window_icon(xfc, railWindow, icon, replaceIcon);
|
||||
rc = TRUE;
|
||||
}
|
||||
- xf_rail_return_window(railWindow);
|
||||
+ xf_rail_return_window(railWindow, FALSE);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -951,7 +951,7 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context,
|
||||
int direction = 0;
|
||||
Window child_window = 0;
|
||||
xfContext* xfc = (xfContext*)context->custom;
|
||||
- xfAppWindow* appWindow = xf_rail_get_window(xfc, localMoveSize->windowId);
|
||||
+ xfAppWindow* appWindow = xf_rail_get_window(xfc, localMoveSize->windowId, FALSE);
|
||||
|
||||
if (!appWindow)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
@@ -1034,7 +1034,7 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context,
|
||||
else
|
||||
xf_EndLocalMoveSize(xfc, appWindow);
|
||||
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
@@ -1047,7 +1047,7 @@ static UINT xf_rail_server_min_max_info(RailClientContext* context,
|
||||
const RAIL_MINMAXINFO_ORDER* minMaxInfo)
|
||||
{
|
||||
xfContext* xfc = (xfContext*)context->custom;
|
||||
- xfAppWindow* appWindow = xf_rail_get_window(xfc, minMaxInfo->windowId);
|
||||
+ xfAppWindow* appWindow = xf_rail_get_window(xfc, minMaxInfo->windowId, FALSE);
|
||||
|
||||
if (appWindow)
|
||||
{
|
||||
@@ -1056,7 +1056,7 @@ static UINT xf_rail_server_min_max_info(RailClientContext* context,
|
||||
minMaxInfo->minTrackHeight, minMaxInfo->maxTrackWidth,
|
||||
minMaxInfo->maxTrackHeight);
|
||||
}
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
@@ -1222,13 +1222,20 @@ BOOL xf_rail_del_window(xfContext* xfc, UINT64 id)
|
||||
if (!xfc->railWindows)
|
||||
return FALSE;
|
||||
|
||||
- return HashTable_Remove(xfc->railWindows, &id);
|
||||
+ xf_lock_x11(xfc);
|
||||
+ const BOOL res = HashTable_Remove(xfc->railWindows, &id);
|
||||
+ xf_unlock_x11(xfc);
|
||||
+ return res;
|
||||
}
|
||||
|
||||
-void xf_rail_return_windowFrom(xfAppWindow* window, const char* file, const char* fkt, size_t line)
|
||||
+void xf_rail_return_windowFrom(xfAppWindow* window, BOOL alreadyLocked, const char* file,
|
||||
+ const char* fkt, size_t line)
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
+ if (alreadyLocked)
|
||||
+ return;
|
||||
+
|
||||
xfAppWindowsUnlockFrom(window->xfc, file, fkt, line);
|
||||
}
|
||||
diff --git a/client/X11/xf_rail.h b/client/X11/xf_rail.h
|
||||
index 2b365b5..dafbd51 100644
|
||||
--- a/client/X11/xf_rail.h
|
||||
+++ b/client/X11/xf_rail.h
|
||||
@@ -38,14 +38,15 @@ void xf_rail_disable_remoteapp_mode(xfContext* xfc);
|
||||
xfAppWindow* xf_rail_add_window(xfContext* xfc, UINT64 id, UINT32 x, UINT32 y, UINT32 width,
|
||||
UINT32 height, UINT32 surfaceId);
|
||||
|
||||
-#define xf_rail_return_window(window) \
|
||||
- xf_rail_return_windowFrom((window), __FILE__, __func__, __LINE__)
|
||||
-void xf_rail_return_windowFrom(xfAppWindow* window, const char* file, const char* fkt, size_t line);
|
||||
-
|
||||
-#define xf_rail_get_window(xfc, id) \
|
||||
- xf_rail_get_windowFrom((xfc), (id), __FILE__, __func__, __LINE__)
|
||||
-xfAppWindow* xf_rail_get_windowFrom(xfContext* xfc, UINT64 id, const char* file, const char* fkt,
|
||||
- size_t line);
|
||||
+#define xf_rail_return_window(window, alreadyLocked) \
|
||||
+ xf_rail_return_windowFrom((window), (alreadyLocked), __FILE__, __func__, __LINE__)
|
||||
+void xf_rail_return_windowFrom(xfAppWindow* window, BOOL alreadyLocked, const char* file,
|
||||
+ const char* fkt, size_t line);
|
||||
+
|
||||
+#define xf_rail_get_window(xfc, id, alreadyLocked) \
|
||||
+ xf_rail_get_windowFrom((xfc), (id), (alreadyLocked), __FILE__, __func__, __LINE__)
|
||||
+xfAppWindow* xf_rail_get_windowFrom(xfContext* xfc, UINT64 id, BOOL alreadyLocked,
|
||||
+ const char* file, const char* fkt, size_t line);
|
||||
|
||||
BOOL xf_rail_del_window(xfContext* xfc, UINT64 id);
|
||||
|
||||
diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c
|
||||
index 8d7bcd6..3a67e0e 100644
|
||||
--- a/client/X11/xf_window.c
|
||||
+++ b/client/X11/xf_window.c
|
||||
@@ -1343,8 +1343,6 @@ void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, i
|
||||
if (ay + height > appWindow->windowOffsetY + appWindow->height)
|
||||
height = (appWindow->windowOffsetY + appWindow->height - 1) - ay;
|
||||
|
||||
- xf_lock_x11(xfc);
|
||||
-
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_SoftwareGdi))
|
||||
{
|
||||
XPutImage(xfc->display, appWindow->pixmap, appWindow->gc, xfc->image, ax, ay, x, y, width,
|
||||
@@ -1354,7 +1352,6 @@ void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, i
|
||||
XCopyArea(xfc->display, appWindow->pixmap, appWindow->handle, appWindow->gc, x, y, width,
|
||||
height, x, y);
|
||||
XFlush(xfc->display);
|
||||
- xf_unlock_x11(xfc);
|
||||
}
|
||||
|
||||
static void xf_AppWindowDestroyImage(xfAppWindow* appWindow)
|
||||
@@ -1411,8 +1408,8 @@ static xfAppWindow* get_windowUnlocked(xfContext* xfc, UINT64 id)
|
||||
return HashTable_GetItemValue(xfc->railWindows, &id);
|
||||
}
|
||||
|
||||
-xfAppWindow* xf_rail_get_windowFrom(xfContext* xfc, UINT64 id, const char* file, const char* fkt,
|
||||
- size_t line)
|
||||
+xfAppWindow* xf_rail_get_windowFrom(xfContext* xfc, UINT64 id, BOOL alreadyLocked,
|
||||
+ const char* file, const char* fkt, size_t line)
|
||||
{
|
||||
if (!xfc)
|
||||
return NULL;
|
||||
@@ -1420,9 +1417,12 @@ xfAppWindow* xf_rail_get_windowFrom(xfContext* xfc, UINT64 id, const char* file,
|
||||
if (!xfc->railWindows)
|
||||
return NULL;
|
||||
|
||||
- xfAppWindowsLockFrom(xfc, file, fkt, line);
|
||||
+ if (!alreadyLocked)
|
||||
+ xfAppWindowsLockFrom(xfc, file, fkt, line);
|
||||
+
|
||||
xfAppWindow* window = get_windowUnlocked(xfc, id);
|
||||
- if (!window)
|
||||
+
|
||||
+ if (!window && !alreadyLocked)
|
||||
xfAppWindowsUnlockFrom(xfc, file, fkt, line);
|
||||
|
||||
return window;
|
||||
@@ -1471,7 +1471,7 @@ UINT xf_AppUpdateWindowFromSurface(xfContext* xfc, gdiGfxSurface* surface)
|
||||
WINPR_ASSERT(xfc);
|
||||
WINPR_ASSERT(surface);
|
||||
|
||||
- xfAppWindow* appWindow = xf_rail_get_window(xfc, surface->windowId);
|
||||
+ xfAppWindow* appWindow = xf_rail_get_window(xfc, surface->windowId, FALSE);
|
||||
if (!appWindow)
|
||||
{
|
||||
WLog_VRB(TAG, "Failed to find a window for id=0x%08" PRIx64, surface->windowId);
|
||||
@@ -1482,7 +1482,6 @@ UINT xf_AppUpdateWindowFromSurface(xfContext* xfc, gdiGfxSurface* surface)
|
||||
UINT32 nrects = 0;
|
||||
const RECTANGLE_16* rects = region16_rects(&surface->invalidRegion, &nrects);
|
||||
|
||||
- xf_lock_x11(xfc);
|
||||
if (swGdi)
|
||||
{
|
||||
if (appWindow->surfaceId != surface->surfaceId)
|
||||
@@ -1537,9 +1536,9 @@ UINT xf_AppUpdateWindowFromSurface(xfContext* xfc, gdiGfxSurface* surface)
|
||||
|
||||
rc = CHANNEL_RC_OK;
|
||||
fail:
|
||||
- xf_rail_return_window(appWindow);
|
||||
+ xf_rail_return_window(appWindow, FALSE);
|
||||
XFlush(xfc->display);
|
||||
- xf_unlock_x11(xfc);
|
||||
+
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1567,7 +1566,7 @@ void xf_XSetTransientForHint(xfContext* xfc, xfAppWindow* window)
|
||||
if (window->ownerWindowId == 0)
|
||||
return;
|
||||
|
||||
- xfAppWindow* parent = xf_rail_get_window(xfc, window->ownerWindowId);
|
||||
+ xfAppWindow* parent = xf_rail_get_window(xfc, window->ownerWindowId, TRUE);
|
||||
if (!parent)
|
||||
return;
|
||||
|
||||
@@ -1578,7 +1577,7 @@ void xf_XSetTransientForHint(xfContext* xfc, xfAppWindow* window)
|
||||
WLog_WARN(TAG, "XSetTransientForHint [%d]{%s}", rc,
|
||||
x11_error_to_string(xfc, rc, buffer, sizeof(buffer)));
|
||||
}
|
||||
- xf_rail_return_window(parent);
|
||||
+ xf_rail_return_window(parent, TRUE);
|
||||
}
|
||||
|
||||
void xfAppWindowsLockFrom(xfContext* xfc, const char* file, const char* fkt, size_t line)
|
||||
@@ -1591,6 +1590,7 @@ void xfAppWindowsLockFrom(xfContext* xfc, const char* file, const char* fkt, siz
|
||||
WLog_PrintMessage(xfc->log, WLOG_MESSAGE_TEXT, level, line, file, fkt, "[rails] locking [%s]", fkt);
|
||||
#endif
|
||||
|
||||
+ xf_lock_x11(xfc);
|
||||
HashTable_Lock(xfc->railWindows);
|
||||
|
||||
#if defined(WITH_VERBOSE_WINPR_ASSERT)
|
||||
@@ -1613,4 +1613,5 @@ void xfAppWindowsUnlockFrom(xfContext* xfc, const char* file, const char* fkt, s
|
||||
#endif
|
||||
|
||||
HashTable_Unlock(xfc->railWindows);
|
||||
+ xf_unlock_x11(xfc);
|
||||
}
|
||||
--
|
||||
2.54.0
|
||||
|
||||
30
codec-planar-fix-bounds-checks.patch
Normal file
30
codec-planar-fix-bounds-checks.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From d9bf1e5fca30a89603accff808b2452750333cb6 Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <armin.novak@thincast.com>
|
||||
Date: Thu, 30 Apr 2026 15:03:21 +0200
|
||||
Subject: [PATCH] [codec,planar] fix bounds checks
|
||||
|
||||
---
|
||||
libfreerdp/codec/planar.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c
|
||||
index 58efbc627..0c4129fb1 100644
|
||||
--- a/libfreerdp/codec/planar.c
|
||||
+++ b/libfreerdp/codec/planar.c
|
||||
@@ -958,12 +958,12 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* WINPR_RESTRICT planar,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- if ((nXDst + nSrcWidth) * bpp > nDstStep)
|
||||
+ if ((nXDst + nSrcWidth) * bpp > nTempStep)
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"planar plane destination (X %" PRIu32 " + width %" PRIu32
|
||||
") * bpp %" PRIu32 " exceeds stride %" PRIu32,
|
||||
- nXDst, nSrcWidth, bpp, nDstStep);
|
||||
+ nXDst, nSrcWidth, bpp, nTempStep);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
--
|
||||
2.52.0
|
||||
37
core-connection-print-SSL-warnings-after-init.patch
Normal file
37
core-connection-print-SSL-warnings-after-init.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From 60ed73552ffdb499dddf06c119be9437da7f9261 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Sun, 29 Dec 2024 10:22:56 +0100
|
||||
Subject: [PATCH] [core,connection] print SSL warnings after init
|
||||
|
||||
---
|
||||
libfreerdp/core/connection.c | 1 +
|
||||
libfreerdp/core/freerdp.c | 1 -
|
||||
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c
|
||||
index 979ccdf60..001b56944 100644
|
||||
--- a/libfreerdp/core/connection.c
|
||||
+++ b/libfreerdp/core/connection.c
|
||||
@@ -319,6 +319,7 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
||||
flags |= WINPR_SSL_INIT_ENABLE_FIPS;
|
||||
|
||||
winpr_InitializeSSL(flags);
|
||||
+ rdp_log_build_warnings(rdp);
|
||||
|
||||
/* FIPS Mode forces the following and overrides the following(by happening later */
|
||||
/* in the command line processing): */
|
||||
diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c
|
||||
index 94dad20a0..715da31d9 100644
|
||||
--- a/libfreerdp/core/freerdp.c
|
||||
+++ b/libfreerdp/core/freerdp.c
|
||||
@@ -802,7 +802,6 @@ BOOL freerdp_context_new_ex(freerdp* instance, rdpSettings* settings)
|
||||
if (!rdp)
|
||||
goto fail;
|
||||
|
||||
- rdp_log_build_warnings(rdp);
|
||||
context->rdp = rdp;
|
||||
context->pubSub = rdp->pubSub;
|
||||
|
||||
--
|
||||
2.51.1
|
||||
|
||||
43
core-tcp-Don-t-ignore-connect-errors.patch
Normal file
43
core-tcp-Don-t-ignore-connect-errors.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 5a856bef31bdbecbaf69bd671d23add9779debd9 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Wed, 14 Jan 2026 11:37:16 +0100
|
||||
Subject: [PATCH] [core,tcp] Don't ignore connect errors
|
||||
|
||||
Backport of commit 0bdd8da0993231216a7bb4d5e6e33e47d817a944.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
---
|
||||
libfreerdp/core/tcp.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c
|
||||
index 8e7ee20bd..6edfb6d71 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -857,12 +857,19 @@ static BOOL freerdp_tcp_connect_timeout(rdpContext* context, int sockfd, struct
|
||||
if (WAIT_OBJECT_0 != status)
|
||||
goto fail;
|
||||
|
||||
- const SSIZE_T res = recv(sockfd, NULL, 0, 0);
|
||||
-
|
||||
- if (res == SOCKET_ERROR)
|
||||
{
|
||||
- if (WSAGetLastError() == WSAECONNRESET)
|
||||
+ INT32 optval = 0;
|
||||
+ socklen_t optlen = sizeof(optval);
|
||||
+ if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (optval != 0)
|
||||
+ {
|
||||
+ char ebuffer[256] = { 0 };
|
||||
+ WLog_DBG(TAG, "connect failed with error: %s [%" PRId32 "]",
|
||||
+ winpr_strerror(optval, ebuffer, sizeof(ebuffer)), optval);
|
||||
goto fail;
|
||||
+ }
|
||||
}
|
||||
|
||||
status = WSAEventSelect(sockfd, handles[0], 0);
|
||||
--
|
||||
2.52.0
|
||||
|
||||
102
core-tcp-Fix-PreferIPv6OverIPv4-fallback-to-IPv4-add.patch
Normal file
102
core-tcp-Fix-PreferIPv6OverIPv4-fallback-to-IPv4-add.patch
Normal file
@ -0,0 +1,102 @@
|
||||
From 4864954a384e4028298e95a19795505f688b21ae Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Wed, 14 Jan 2026 11:38:11 +0100
|
||||
Subject: [PATCH] [core,tcp] Fix PreferIPv6OverIPv4 fallback to IPv4 addresses
|
||||
|
||||
Backport of commit 0bdd8da0993231216a7bb4d5e6e33e47d817a944.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
---
|
||||
libfreerdp/core/tcp.c | 61 ++++++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 51 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c
|
||||
index 6edfb6d71..83cc9af1e 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -1081,6 +1081,53 @@ int freerdp_tcp_connect(rdpContext* context, const char* hostname, int port, DWO
|
||||
return transport_tcp_connect(context->rdp->transport, hostname, port, timeout);
|
||||
}
|
||||
|
||||
+static struct addrinfo* reorder_addrinfo_by_preference(rdpContext* context, struct addrinfo* addr)
|
||||
+{
|
||||
+ WINPR_ASSERT(context);
|
||||
+ WINPR_ASSERT(addr);
|
||||
+
|
||||
+ const BOOL preferIPv6 =
|
||||
+ freerdp_settings_get_bool(context->settings, FreeRDP_PreferIPv6OverIPv4);
|
||||
+ if (!preferIPv6)
|
||||
+ return addr;
|
||||
+
|
||||
+ struct addrinfo* ipv6Head = NULL;
|
||||
+ struct addrinfo* ipv6Tail = NULL;
|
||||
+ struct addrinfo* otherHead = NULL;
|
||||
+ struct addrinfo* otherTail = NULL;
|
||||
+
|
||||
+ /* Partition the list into IPv6 and other addresses */
|
||||
+ while (addr)
|
||||
+ {
|
||||
+ struct addrinfo* next = addr->ai_next;
|
||||
+ addr->ai_next = NULL;
|
||||
+
|
||||
+ if (addr->ai_family == AF_INET6)
|
||||
+ {
|
||||
+ if (!ipv6Head)
|
||||
+ ipv6Head = addr;
|
||||
+ else
|
||||
+ ipv6Tail->ai_next = addr;
|
||||
+ ipv6Tail = addr;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (!otherHead)
|
||||
+ otherHead = addr;
|
||||
+ else
|
||||
+ otherTail->ai_next = addr;
|
||||
+ otherTail = addr;
|
||||
+ }
|
||||
+ addr = next;
|
||||
+ }
|
||||
+
|
||||
+ /* Concatenate the lists */
|
||||
+ if (ipv6Tail)
|
||||
+ ipv6Tail->ai_next = otherHead;
|
||||
+
|
||||
+ return ipv6Head ? ipv6Head : otherHead;
|
||||
+}
|
||||
+
|
||||
static int get_next_addrinfo(rdpContext* context, struct addrinfo* input, struct addrinfo** result,
|
||||
UINT32 errorCode)
|
||||
{
|
||||
@@ -1091,14 +1138,6 @@ static int get_next_addrinfo(rdpContext* context, struct addrinfo* input, struct
|
||||
if (!addr)
|
||||
goto fail;
|
||||
|
||||
- if (freerdp_settings_get_bool(context->settings, FreeRDP_PreferIPv6OverIPv4))
|
||||
- {
|
||||
- while (addr && (addr->ai_family != AF_INET6))
|
||||
- addr = addr->ai_next;
|
||||
- if (!addr)
|
||||
- addr = input;
|
||||
- }
|
||||
-
|
||||
/* We want to force IPvX, abort if not detected */
|
||||
const UINT32 IPvX = freerdp_settings_get_uint32(context->settings, FreeRDP_ForceIPvX);
|
||||
switch (IPvX)
|
||||
@@ -1237,9 +1276,11 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons
|
||||
|
||||
/* By default we take the first returned entry.
|
||||
*
|
||||
- * If PreferIPv6OverIPv4 = TRUE we force to IPv6 if there
|
||||
- * is such an address available, but fall back to first if not found
|
||||
+ * If PreferIPv6OverIPv4 = TRUE we reorder addresses by preference:
|
||||
+ * IPv6 addresses come first, then other addresses.
|
||||
*/
|
||||
+ result = reorder_addrinfo_by_preference(context, result);
|
||||
+
|
||||
const int rc =
|
||||
get_next_addrinfo(context, result, &addr, FREERDP_ERROR_DNS_NAME_NOT_FOUND);
|
||||
if (rc < 0)
|
||||
--
|
||||
2.52.0
|
||||
|
||||
76
core-tcp-Try-next-DNS-entry-on-connect-failure.patch
Normal file
76
core-tcp-Try-next-DNS-entry-on-connect-failure.patch
Normal file
@ -0,0 +1,76 @@
|
||||
From e4adf227177fd807f47f8621a5e2568748619a23 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Wed, 14 Jan 2026 11:34:53 +0100
|
||||
Subject: [PATCH] [core,tcp] Try next DNS entry on connect failure
|
||||
|
||||
Backport of commit bd67348eb3380a66b544835346191bd2138a5ba4.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
---
|
||||
libfreerdp/core/tcp.c | 41 ++++++++++++++++++++++-------------------
|
||||
1 file changed, 22 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c
|
||||
index 53e3a412f..8e7ee20bd 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -1241,34 +1241,37 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons
|
||||
do
|
||||
{
|
||||
sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
+ if (sockfd >= 0)
|
||||
+ {
|
||||
+ if ((peerAddress = freerdp_tcp_address_to_string(
|
||||
+ (const struct sockaddr_storage*)addr->ai_addr, NULL)) != NULL)
|
||||
+ {
|
||||
+ WLog_DBG(TAG, "connecting to peer %s", peerAddress);
|
||||
+ free(peerAddress);
|
||||
+ }
|
||||
+
|
||||
+ if (!freerdp_tcp_connect_timeout(context, sockfd, addr->ai_addr,
|
||||
+ addr->ai_addrlen, timeout))
|
||||
+ {
|
||||
+ close(sockfd);
|
||||
+ sockfd = -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (sockfd < 0)
|
||||
{
|
||||
const int lrc = get_next_addrinfo(context, addr->ai_next, &addr,
|
||||
FREERDP_ERROR_CONNECT_FAILED);
|
||||
if (lrc < 0)
|
||||
+ {
|
||||
+ freeaddrinfo(result);
|
||||
+ freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
|
||||
+ WLog_ERR(TAG, "failed to connect to %s", hostname);
|
||||
return lrc;
|
||||
+ }
|
||||
}
|
||||
} while (sockfd < 0);
|
||||
|
||||
- if ((peerAddress = freerdp_tcp_address_to_string(
|
||||
- (const struct sockaddr_storage*)addr->ai_addr, NULL)) != NULL)
|
||||
- {
|
||||
- WLog_DBG(TAG, "connecting to peer %s", peerAddress);
|
||||
- free(peerAddress);
|
||||
- }
|
||||
-
|
||||
- if (!freerdp_tcp_connect_timeout(context, sockfd, addr->ai_addr, addr->ai_addrlen,
|
||||
- timeout))
|
||||
- {
|
||||
- freeaddrinfo(result);
|
||||
- close(sockfd);
|
||||
-
|
||||
- freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
|
||||
-
|
||||
- WLog_ERR(TAG, "failed to connect to %s", hostname);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
freeaddrinfo(result);
|
||||
}
|
||||
}
|
||||
--
|
||||
2.52.0
|
||||
|
||||
39
core-tcp-fix-double-free-in-get_next_addrinfo.patch
Normal file
39
core-tcp-fix-double-free-in-get_next_addrinfo.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 0a660bf3b3cf2660a4fa15bd37d8b8b3d03fbfef Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Wed, 14 Jan 2026 12:55:42 +0100
|
||||
Subject: [PATCH] [core,tcp] fix double free in get_next_addrinfo
|
||||
|
||||
Backport of commit 48197426444b7b3587874b5eae175af1113beab8.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
||||
---
|
||||
libfreerdp/core/tcp.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c
|
||||
index 83cc9af1e..a3e12d14b 100644
|
||||
--- a/libfreerdp/core/tcp.c
|
||||
+++ b/libfreerdp/core/tcp.c
|
||||
@@ -1164,7 +1164,7 @@ static int get_next_addrinfo(rdpContext* context, struct addrinfo* input, struct
|
||||
|
||||
fail:
|
||||
freerdp_set_last_error_if_not(context, errorCode);
|
||||
- freeaddrinfo(input);
|
||||
+ *result = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1284,7 +1284,10 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons
|
||||
const int rc =
|
||||
get_next_addrinfo(context, result, &addr, FREERDP_ERROR_DNS_NAME_NOT_FOUND);
|
||||
if (rc < 0)
|
||||
+ {
|
||||
+ freeaddrinfo(result);
|
||||
return rc;
|
||||
+ }
|
||||
|
||||
do
|
||||
{
|
||||
--
|
||||
2.52.0
|
||||
|
||||
102
freerdp.spec
102
freerdp.spec
@ -30,7 +30,7 @@
|
||||
Name: freerdp
|
||||
Epoch: 2
|
||||
Version: 3.10.3
|
||||
Release: 5%{?dist}.8
|
||||
Release: 12%{?dist}.6
|
||||
Summary: Free implementation of the Remote Desktop Protocol (RDP)
|
||||
|
||||
# The effective license is Apache-2.0 but:
|
||||
@ -56,6 +56,15 @@ Patch2: Use-default-threadpool.patch
|
||||
Patch3: Default-minimum-thread-count.patch
|
||||
Patch4: Limit-minimum-threadpool-size.patch
|
||||
|
||||
# https://issues.redhat.com/browse/RHEL-73724
|
||||
Patch: core-connection-print-SSL-warnings-after-init.patch
|
||||
|
||||
# https://issues.redhat.com/browse/RHEL-140099
|
||||
Patch: core-tcp-Try-next-DNS-entry-on-connect-failure.patch
|
||||
Patch: core-tcp-Don-t-ignore-connect-errors.patch
|
||||
Patch: core-tcp-Fix-PreferIPv6OverIPv4-fallback-to-IPv4-add.patch
|
||||
Patch: core-tcp-fix-double-free-in-get_next_addrinfo.patch
|
||||
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/c4a7c371342edf0d307cea728f56d3302f0ab38c
|
||||
Patch: gdi-gfx-properly-clamp-SurfaceToSurface.patch
|
||||
|
||||
@ -227,6 +236,40 @@ Patch: codec-clear-update-clear_glyph_entry-count-after-alloc.patch
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/a48dbde2c8a5b8b70a9d1c045d969a71afd6284c
|
||||
Patch: cache-persist-use-winpr_aligned_calloc.patch
|
||||
|
||||
# CVE-2026-25952
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/1994e9844212a6dfe0ff12309fef520e888986b5
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/78fd7f580d5f9e6d9d582d82e5ea96003844fbdf
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/4ff57b68c2960fa414d03c78ff0e0660be1cc5bd
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/a278ff74117444c635c50ffa5084ecf517171f5a
|
||||
Patch: client-x11-lock-appwindow.patch
|
||||
Patch: client-x11-improve-rails-window-locking.patch
|
||||
Patch: client-x11-refactor-locking.patch
|
||||
Patch: client-x11-fix-deadlock-on-output-expose.patch
|
||||
|
||||
# CVE-2026-40033
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/f951d8677ce6d34d9778b951f73b3072b01853cb
|
||||
Patch: gdi-gfx-fix-bounds-checks.patch
|
||||
|
||||
# CVE-2026-44421
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/b877c8c0fef1b5ccda29ccd5a1a58696486545ed
|
||||
Patch: gdi-gfx-ensure-the-cache-element-can-hold-the-data.patch
|
||||
|
||||
# CVE-2026-45700
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/4a065a941ae134a0433d1497c03b3c3eb91b9f85
|
||||
Patch: codec-planar-fix-bounds-checks.patch
|
||||
|
||||
# CVE-2026-44420
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/0fba1f4dbff7585c9c99873d7c07d7dac46510c3
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/d00dc5d3be369fb400344eb12e6882db2ee184f0
|
||||
Patch: channels-cliprdr-validate-capabilitySetLength-in-server-caps.patch
|
||||
Patch: channels-cliprdr-abort-on-duplicate-caps.patch
|
||||
|
||||
# CVE-2026-44422
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/668fcb49d4856fad28f685db54a572af2a284b50
|
||||
# https://github.com/FreeRDP/FreeRDP/commit/ae03a9ff981ce7be1ab09dba2cd319d54984f910
|
||||
Patch: channels-rdpear-fix-ndr_read-checks.patch
|
||||
Patch: channels-rdpear-disable-ndr-pointer-aliasing.patch
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: alsa-lib-devel
|
||||
@ -398,6 +441,7 @@ find . -name "*.c" -exec chmod 664 {} \;
|
||||
-DWITH_TIMEZONE_COMPILED=OFF \
|
||||
-DWITH_TIMEZONE_FROM_FILE=ON \
|
||||
-DWITH_URIPARSER=%{?_with_uriparser:ON}%{?!_with_uriparser:OFF} \
|
||||
-DWITH_VERBOSE_WINPR_ASSERT=OFF \
|
||||
-DWITH_VIDEO_FFMPEG=%{?_with_ffmpeg:ON}%{?!_with_ffmpeg:OFF} \
|
||||
-DWITH_WAYLAND=ON \
|
||||
-DWITH_WEBVIEW=%{?_with_webview:ON}%{?!_with_webview:OFF} \
|
||||
@ -549,7 +593,16 @@ find %{buildroot} -name "*.a" -delete
|
||||
%{_libdir}/pkgconfig/winpr-tools3.pc
|
||||
|
||||
%changelog
|
||||
* Wed Apr 29 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-5.8
|
||||
* Mon Jun 29 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-12.6
|
||||
- Backport several CVE fixes (CVE-2026-40033, CVE-2026-44420, CVE-2026-44421,
|
||||
CVE-2026-44422, CVE-2026-45700)
|
||||
Resolves: RHEL-186978, RHEL-186967, RHEL-186958, RHEL-186950, RHEL-186093
|
||||
|
||||
* Tue May 05 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-12.5
|
||||
- Lock appWindow to fix use-after-free in RAIL mode (CVE-2026-25952)
|
||||
Resolves: RHEL-159848
|
||||
|
||||
* Wed Apr 29 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-12.4
|
||||
- Fix double free in xf_rail_window_common cleanup (CVE-2026-26986)
|
||||
- Fix clipboard use-after-free during auto-reconnect (CVE-2026-25997)
|
||||
- Fix heap-buffer-overflow in bitmap_cache_put (CVE-2026-29775)
|
||||
@ -559,37 +612,48 @@ find %{buildroot} -name "*.a" -delete
|
||||
- Update PERSISTENT_CACHE_ENTRY::size after realloc (CVE-2026-33987)
|
||||
- Update CLEAR_GLYPH_ENTRY::count after alloc (CVE-2026-33985)
|
||||
- Use winpr_aligned_calloc in persistent cache (CVE-2026-33982)
|
||||
Resolves: RHEL-159803, RHEL-159659, RHEL-161033, RHEL-161468
|
||||
Resolves: RHEL-161504, RHEL-161071, RHEL-163653, RHEL-167791, RHEL-162930
|
||||
Resolves: RHEL-159804, RHEL-159660, RHEL-161034, RHEL-161469
|
||||
Resolves: RHEL-161505, RHEL-161072, RHEL-163654, RHEL-168462, RHEL-162931
|
||||
|
||||
* Fri Apr 10 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-5.6
|
||||
* Fri Apr 10 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-12.2
|
||||
- Update CLEAR_VBAR_ENTRY size after alloc (CVE-2026-33984)
|
||||
- Fail progressive_rfx_quant_sub on invalid values (CVE-2026-33983)
|
||||
Resolves: RHEL-162946, RHEL-162962
|
||||
Resolves: RHEL-162947, RHEL-162963
|
||||
|
||||
* Tue Mar 31 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-5.5
|
||||
* Thu Apr 09 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-12.1
|
||||
- Rebuilt for errata
|
||||
Resolves: RHEL-155980
|
||||
|
||||
* Tue Mar 31 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-12
|
||||
- Fix use of nsc_process_message
|
||||
- Increase timeout for TestSynchCritical
|
||||
Resolves: RHEL-155979
|
||||
Resolves: RHEL-155980
|
||||
|
||||
* Fri Mar 27 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-5.4
|
||||
* Fri Mar 27 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-11
|
||||
- Backport several CVE fixes
|
||||
Resolves: RHEL-147948, RHEL-147949, RHEL-147956, RHEL-147963, RHEL-147964
|
||||
Resolves: RHEL-147972, RHEL-147979, RHEL-147984, RHEL-147985, RHEL-148898
|
||||
Resolves: RHEL-148978, RHEL-148984, RHEL-149051, RHEL-155979
|
||||
Resolves: RHEL-147950, RHEL-147951, RHEL-147966, RHEL-147967, RHEL-147971
|
||||
Resolves: RHEL-147997, RHEL-147998, RHEL-148006, RHEL-148007, RHEL-148900
|
||||
Resolves: RHEL-148986, RHEL-148989, RHEL-149053, RHEL-155980
|
||||
|
||||
* Wed Mar 25 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-5.3
|
||||
* Wed Mar 25 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-10
|
||||
- Backport several CVE fixes
|
||||
Resolves: RHEL-151975, RHEL-152202
|
||||
Resolves: RHEL-151976, RHEL-152203
|
||||
|
||||
* Tue Feb 17 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-5.2
|
||||
* Tue Feb 17 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-9
|
||||
- Backport several CVE fixes
|
||||
Resolves: RHEL-147912, RHEL-148815, RHEL-148859, RHEL-148892, RHEL-148973
|
||||
Resolves: RHEL-147913, RHEL-148817, RHEL-148861, RHEL-148977, RHEL-148894
|
||||
|
||||
* Tue Jan 27 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-5.1
|
||||
* Tue Jan 27 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-8
|
||||
- Backport several CVE fixes
|
||||
Resolves: RHEL-142413, RHEL-142397, RHEL-142381, RHEL-142365, RHEL-142349
|
||||
Resolves: RHEL-142333, RHEL-142317
|
||||
Resolves: RHEL-142414, RHEL-142398, RHEL-142382, RHEL-142366, RHEL-142350
|
||||
Resolves: RHEL-142334, RHEL-142318
|
||||
|
||||
* Fri Jan 16 2026 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-7
|
||||
- Try next DNS entry on connect failure
|
||||
Resolves: RHEL-140099
|
||||
|
||||
* Tue Dec 16 2025 Ondrej Holy <oholy@redhat.com> - 2:3.10.3-6
|
||||
- Fix broken SSL checks and disable runtime checks (RHEL-73724)
|
||||
|
||||
* Tue Sep 30 2025 Marek Kasik <mkasik@redhat.com> - 2:3.10.3-5
|
||||
- Silence abidiff
|
||||
|
||||
28
gdi-gfx-ensure-the-cache-element-can-hold-the-data.patch
Normal file
28
gdi-gfx-ensure-the-cache-element-can-hold-the-data.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 45898fbb38d755d2c3211ed6064e13ee9815f24c Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <armin.novak@thincast.com>
|
||||
Date: Thu, 30 Apr 2026 10:49:01 +0200
|
||||
Subject: [PATCH] [gdi,gfx] ensure the cache element can hold the data
|
||||
|
||||
For future color format compatibility ensure that the bytes per
|
||||
pixel are MAX(4, FreeRDPGetBytesPerPixel(format))
|
||||
---
|
||||
libfreerdp/gdi/gfx.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libfreerdp/gdi/gfx.c b/libfreerdp/gdi/gfx.c
|
||||
index d22405445..7ac597d92 100644
|
||||
--- a/libfreerdp/gdi/gfx.c
|
||||
+++ b/libfreerdp/gdi/gfx.c
|
||||
@@ -1414,7 +1414,9 @@ static gdiGfxCacheEntry* gdi_GfxCacheEntryNew(UINT64 cacheKey, UINT32 width, UIN
|
||||
cacheEntry->width = width;
|
||||
cacheEntry->height = height;
|
||||
cacheEntry->format = format;
|
||||
- cacheEntry->scanline = gfx_align_scanline(cacheEntry->width * 4, 16);
|
||||
+
|
||||
+ const UINT32 bpp = MAX(4, FreeRDPGetBytesPerPixel(format));
|
||||
+ cacheEntry->scanline = gfx_align_scanline(cacheEntry->width * bpp, 16);
|
||||
|
||||
if ((cacheEntry->width > 0) && (cacheEntry->height > 0))
|
||||
{
|
||||
--
|
||||
2.52.0
|
||||
31
gdi-gfx-fix-bounds-checks.patch
Normal file
31
gdi-gfx-fix-bounds-checks.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From f2b44427946bf42128609b66b4f6623c9b58a482 Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <armin.novak@thincast.com>
|
||||
Date: Thu, 30 Apr 2026 10:04:24 +0200
|
||||
Subject: [PATCH] [gdi,gfx] fix bounds checks
|
||||
|
||||
---
|
||||
libfreerdp/gdi/gfx.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/gdi/gfx.c b/libfreerdp/gdi/gfx.c
|
||||
index 3cbea681d..d22405445 100644
|
||||
--- a/libfreerdp/gdi/gfx.c
|
||||
+++ b/libfreerdp/gdi/gfx.c
|
||||
@@ -1519,10 +1519,12 @@ static UINT gdi_CacheToSurface(RdpgfxClientContext* context,
|
||||
if (!is_rect_valid(&rect, surface->width, surface->height))
|
||||
goto fail;
|
||||
|
||||
+ const UINT32 w = rect.right - rect.left;
|
||||
+ const UINT32 h = rect.bottom - rect.top;
|
||||
if (!freerdp_image_copy_no_overlap(surface->data, surface->format, surface->scanline,
|
||||
- destPt->x, destPt->y, cacheEntry->width,
|
||||
- cacheEntry->height, cacheEntry->data, cacheEntry->format,
|
||||
- cacheEntry->scanline, 0, 0, NULL, FREERDP_FLIP_NONE))
|
||||
+ destPt->x, destPt->y, w, h, cacheEntry->data,
|
||||
+ cacheEntry->format, cacheEntry->scanline, 0, 0, NULL,
|
||||
+ FREERDP_FLIP_NONE))
|
||||
goto fail;
|
||||
|
||||
invalidRect = rect;
|
||||
--
|
||||
2.52.0
|
||||
Loading…
Reference in New Issue
Block a user