From 0421b53fcb4a80c95f51342e4a2c40c68a4101d3 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Mon, 19 Jan 2026 08:52:51 +0100 Subject: [PATCH 1/2] [client,x11] fix double free in case of invalid pointer --- client/X11/xf_graphics.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index df95a22b5..9d432c98b 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -289,7 +289,6 @@ static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer) #ifdef WITH_XCURSOR UINT32 CursorFormat = 0; - size_t size = 0; xfContext* xfc = (xfContext*)context; xfPointer* xpointer = (xfPointer*)pointer; @@ -304,19 +303,18 @@ static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer) xpointer->nCursors = 0; xpointer->mCursors = 0; - size = 1ull * pointer->height * pointer->width * FreeRDPGetBytesPerPixel(CursorFormat); + const size_t size = + 1ull * pointer->height * pointer->width * FreeRDPGetBytesPerPixel(CursorFormat); - if (!(xpointer->cursorPixels = (XcursorPixel*)winpr_aligned_malloc(size, 16))) + xpointer->cursorPixels = (XcursorPixel*)winpr_aligned_malloc(size, 16); + if (!xpointer->cursorPixels) goto fail; if (!freerdp_image_copy_from_pointer_data( (BYTE*)xpointer->cursorPixels, CursorFormat, 0, 0, 0, pointer->width, pointer->height, pointer->xorMaskData, pointer->lengthXorMask, pointer->andMaskData, pointer->lengthAndMask, pointer->xorBpp, &context->gdi->palette)) - { - winpr_aligned_free(xpointer->cursorPixels); goto fail; - } #endif From 52106a26726a2aba77aa6d86014d2eb3507f0783 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Mon, 19 Jan 2026 08:58:22 +0100 Subject: [PATCH 2/2] [cache,offscreen] invalidate bitmap before free First ensure the bitmap is no longer used for drawing before calling the free function. --- libfreerdp/cache/offscreen.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libfreerdp/cache/offscreen.c b/libfreerdp/cache/offscreen.c index 91fa38f32..d3c85f95d 100644 --- a/libfreerdp/cache/offscreen.c +++ b/libfreerdp/cache/offscreen.c @@ -164,8 +164,6 @@ void offscreen_cache_put(rdpOffscreenCache* offscreenCache, UINT32 index, rdpBit void offscreen_cache_delete(rdpOffscreenCache* offscreenCache, UINT32 index) { - rdpBitmap* prevBitmap = NULL; - WINPR_ASSERT(offscreenCache); if (index >= offscreenCache->maxEntries) @@ -174,10 +172,16 @@ void offscreen_cache_delete(rdpOffscreenCache* offscreenCache, UINT32 index) return; } - prevBitmap = offscreenCache->entries[index]; + rdpBitmap* prevBitmap = offscreenCache->entries[index]; if (prevBitmap != NULL) + { + WINPR_ASSERT(offscreenCache->context); + + /* Ensure that the bitmap is no longer used in GDI */ + IFCALL(prevBitmap->SetSurface, offscreenCache->context, NULL, FALSE); Bitmap_Free(offscreenCache->context, prevBitmap); + } offscreenCache->entries[index] = NULL; }