Skip to content

Refresh stable-2.0 base: rebase WSLg patches from FreeRDP 2.4.0 onto current upstream stable-2.0 (2.11.8-dev + CVE-2026-24684)#8

Draft
benhillis wants to merge 531 commits into
workingfrom
user/benhill/freerdp-stable-2.0-refresh
Draft

Refresh stable-2.0 base: rebase WSLg patches from FreeRDP 2.4.0 onto current upstream stable-2.0 (2.11.8-dev + CVE-2026-24684)#8
benhillis wants to merge 531 commits into
workingfrom
user/benhill/freerdp-stable-2.0-refresh

Conversation

@benhillis
Copy link
Copy Markdown
Member

Draft — do not merge until WSLg integration changes land and runtime smoke-test from Windows host passes.

Summary

Refresh microsoft/FreeRDP-mirror from the abandoned 2.4.0-era working branch (frozen 2023-08-01 at c4030980) onto the current tip of upstream FreeRDP/FreeRDP stable-2.0 (9fa9dd34f, version 2.11.8-dev, including the CVE-2026-24684 backport).

After this lands, consumers will pick up ~3 years of upstream stable-2.0 backports and security fixes that the mirror was missing.

Why a new branch, not a force-push on working?

working is what the wslg-build pipeline consumes (freerdpRef: working). Force-pushing it would break CI globally for anyone in flight. This PR introduces the rebased history as a separate branch so it can be reviewed and merge-fast-forwarded into working only after the wslg side is staged.

What was carried from old working → new branch

Of the 15 commits on origin/working since the FreeRDP 2.4.0 tag:

  • 7 are upstream cherry-picks already present in current upstream stable-2.0 — dropped (redundant)
  • 2 are a net-null revert pair (74f5982 + c403098, the 2.10.0 try) — dropped
  • 1 is a merge commit — dropped (content carried via 18d1e7a)
  • 5 are substantive Microsoft additions — 3 of these are carried as commits below, 2 are part of the WSLg-internal rdpapplist evolution (added then removed in the mirror; the channel now lives outside FreeRDP in wslg/rdpapplist/)

Carried commits

  1. channels/server: port WSLg gfxredir support and AF_VSOCK listener
    Forward-port of Hideyuki's a0c6bcd onto current stable-2.0:

    • New channels/gfxredir/ server channel (graphics redirection, consumed by weston-mirror's rdp-backend via dlopen+dlsym).
    • Public headers include/freerdp/{channels,server}/gfxredir.h.
    • RECTANGLE_32 in include/freerdp/types.h.
    • WITH_CHANNEL_GFXREDIR + 3 cmakedefines in config.h.in.
    • channels/server/channels.c registration (merged alongside upstream's new telemetry/rdpecam/ainput).
    • libfreerdp/core/listener.c: WSAEventSelect(FD_READ|FD_ACCEPT|FD_CLOSE) + AF_VSOCK peer handling (required for WSLg's HV_SOCK transport between Linux guest and mstsc on Windows host).

    Deliberately not carried (upstream already has these; carrying them would dupe or conflict):

    • rdpsnd_main.c use_dynamic_virtual_channel / ChannelIdAssigned (upstream now has this verbatim)
    • include/freerdp/server/rdpsnd.h field + callback decl
    • include/freerdp/rail.h TS_RAIL_CLIENTSTATUS_* (upstream has these plus SUPPRESS_ICON_ORDERS which the old patch lacked)
    • libfreerdp/core/nego.c whitespace + comments
    • include/freerdp/update.h offsetOrders — upstream now exposes this field as size_t (correct for the Stream_GetLength/SetPosition consumers in libfreerdp/core/update.c); Microsoft's UINT16 version would silently duplicate the struct member and break compile.
    • azure-pipelines.yml — stale Microsoft-internal CI; real CI lives in wslg-build.
    • channels/rdpapplist/ — moved out of FreeRDP into wslg/rdpapplist/ as a standalone meson project.
  2. add Hebrew (Standard) keyboard layout ID (#3) — clean cherry-pick of c574044.

  3. Microsoft mandatory file — clean cherry-pick of 18d1e7a (SECURITY.md).

Validation performed locally

Built the full WSLg docker image end-to-end (./build-and-export.sh, all 88 build steps pass):

Check Result
FreeRDP compiles on stable-2.0 + this rebase
Weston's rdp-backend links against the new FreeRDP
Full system distroless image builds
libfreerdp-server2.so exports gfxredir_server_context_new ✅ (the dlsym target in microsoft/weston-mirror libweston/backend-rdp/rdprail.c)
libfreerdp-server2.so exports gfxredir_server_context_free
Zero exported-symbol regressions vs old working build (43 baseline symbols all preserved)
8 new server channel symbols added by upstream (telemetry_server_context_*, cam_dev_enum_server_context_*, camera_device_server_context_*, ainput_server_context_*) ℹ️ informational

What this PR does NOT do

  • Does not change working. Reviewers can fast-forward working onto this branch in a separate operation once the wslg-build side is staged.
  • Does not fix the FreeRDP 2.x EOL problem. Upstream officially considers 2.x out of scope (per FreeRDP/FreeRDP SECURITY.md). Moving to FreeRDP 3.x is a separate, larger effort — needs corresponding work in microsoft/weston-mirror (the abandoned build_with_freerdp_v3.8.0 branch is a head-start). This PR is the largest available short-term mitigation that keeps the existing 2.x codebase working.
  • Does not include a runtime smoke-test from a real Windows host — needs to be performed manually before fast-forwarding working.

Related

akallabeth and others added 30 commits October 20, 2022 08:29
* Added log messages for failure to load a provider
* Add code to clean up loaded providers on shutdown

(cherry picked from commit 4db4b4c)
(cherry picked from commit d48cd82)
(cherry picked from commit 6f62d30)
(cherry picked from commit f3082b3)
* Expose type CONNECTION_STATE
* Add getter freerdp_get_state
* Add helper freerdp_state_string

(cherry picked from commit 32b3f54)
The proxy server component might receive input related events
before the proxy client has established the connection to the
target machine.
With this change, the current keyboard state is cached and sent
to the target when it is ready. All input events received before
the target is ready are discarded.

(cherry picked from commit 4d23bc9)
(cherry picked from commit 731f841)
* Compare WCHAR strings up to n characters

(cherry picked from commit 8178ed2)
Check that canonical path is a subpath of the shared directory

(cherry picked from commit 844c94e)
The check was inverted, setting the flag properly now

(cherry picked from commit 73a722e)
If a cursor is scaled, ensure the result size is at least 1x1 pixel
wide.

(cherry picked from commit 0ebc468)
mstsc/msrdc includes an optional correlation info
(RDP_NEG_CORRELATION_INFO) during connection negotiation. This confuses
FreeRDP which interpret this as a cookie and eventually fails the
negotiation, preventing a successful connection to these RDP client.

This commit addresses 3 things.

1) When processing connection token or cookie, skip if the remaining
bytes are neither.
2) After processing the RDP_NEG_REQ info, skip the optional correlation
info (RDP_NEG_CORRELATION_INFO) if one is present.
3) Allow local connection without server certificate when the client
inherently trust the server.

(cherry picked from commit 592f8d9)
rfc5929 mandates some specific hashes for the binding algorithm

(cherry picked from commit 3a10bcd)
Split windows API emulation from custom functions
Including both might yield issues with OpenSSL headers

(cherry picked from commit d03f230)
* Renamed custom winpr crypto function header
* Added compatiblity header

(cherry picked from commit 23f6366)
akallabeth and others added 27 commits April 24, 2026 00:06
Do sanity checks for rpcconn_common_hdr_t::auth_length read from
network, abort if the value is out of range.

(cherry picked from commit 4ac0b64)
…3-stable-2.0

[stable-2.0] Backport CVE-2026-33983: Fail progressive_rfx_quant_sub on invalid values
…2-stable-2.0

[stable-2.0] Backport CVE-2026-33952: [core,gateway] Check rpcconn_common_hdr_t::auth_length is valid
…7-stable-2.0

[stable-2.0] Backport CVE-2026-31897: [codec,planar] add early length check to avoid oob read
…7-stable-2.0

[stable-2.0] Backport CVE-2026-33977: [codec,dsp] fix IMA ADPCM sample clamping
…1-stable-2.0

[stable-2.0] Backport CVE-2024-32661: [core,info] missing null check in rdp_write_logon_info_v1
To avoid issues with invalid audio format settings always check before
use.

(cherry picked from commit 03b48b3)
* assert array indices where caller value is an internal constant
* add missing length/bounds checks

(cherry picked from commit 16df230)
…5-stable-2.0

[stable-2.0] Backport CVE-2026-31885: [codec,dsp] fix array bounds checks (+CVE-2026-31883)
…4-stable-2.0

[stable-2.0] Backport CVE-2026-31884: [codec,dsp] add format checks
Backport of d9ca272 to stable-2.0.

Adapted to stable-2.0 plugin layout (no GENERIC_DYNVC_PLUGIN base):
- Lock initialization moved to DVCPluginEntry where the plugin is
  allocated; deletion added to ainput_plugin_terminated.
- Callback type adjusted: AINPUT_CHANNEL_CALLBACK (vs upstream's
  GENERIC_CHANNEL_CALLBACK) accessed via ainput->listener_callback
  rather than ainput->base.listener_callback.
- Variable declarations hoisted to start of function for stable-2.0
  C89-compatible style.

(cherry picked from commit d9ca272)
Backport of upstream commit d3e8b3b
to stable-2.0.

The stable-2.0 cliprdr cache is a pair of plain pointers
(clipboard->data and clipboard->data_raw), not the upstream wHashTable
introduced after the 2.x line.  The same race exists, however:

  - xf_cliprdr_server_format_data_response runs on the cliprdr channel
    thread.  It calls xf_cliprdr_clear_cached_data (free + NULL) and
    then re-populates clipboard->data / data_raw.
  - xf_cliprdr_process_selection_request runs on the X11 event thread
    and reads clipboard->data / data_raw, passing them to
    xf_cliprdr_provide_data -> XChangeProperty.

If the channel thread's free races with the X11 thread's read, the
X11 thread can hand a freed buffer to XChangeProperty (heap UAF).

Mirror the upstream fix by introducing a CRITICAL_SECTION protecting
the cache, and lock around every site that reads, writes, or frees
clipboard->data / data_raw:

  * xf_cliprdr_process_selection_request - lock around the read +
    provide_data + (else branch) clear+request_data block.
  * xf_cliprdr_server_format_list - lock around the clear call.
  * xf_cliprdr_server_format_data_response - lock from the initial
    clear through provide_data, including the early-return on
    SrcSize == 0.

Lock is initialized in xf_clipboard_new (with a clean-up in the
error path) and destroyed in xf_clipboard_free.

Source: FreeRDP@d3e8b3b
…2-stable-2.0

[stable-2.0] Backport CVE-2026-25942: [client,x11] stringify functions for RAILS
…3-stable-2.0

[stable-2.0] Backport CVE-2026-24683: [channels,ainput] lock context when updating listener
…9-stable-2.0

[stable-2.0] Backport CVE-2026-25959: [client,x11] lock cache when providing data
Backport of upstream commit 622bb7b
to the stable-2.0 branch. Addresses CVE-2026-24684.

The original cleanup_internals() did not terminate the rdpsnd helper
thread before releasing channel context memory, so any pending callback
on that thread could observe freed audio_formats / pool state.

This change extracts the existing terminate-and-free logic into
rdpsnd_terminate_thread() and calls it at the start of
cleanup_internals(). rdpsnd_virtual_channel_event_terminated() now uses
the same helper, mirroring the upstream layout.

Compiles cleanly on stable-2.0; no public API change.
Backport of upstream commit ffad58f
to stable-2.0. Addresses CVE-2026-29775.

Older RDP servers can send a cache index that is one past the
configured BitmapCacheV2NumCells, causing an out-of-bounds write into
bitmapCache->cells. Fix by overallocating one extra cell slot, matching
the upstream remediation.

stable-2.0 reads BitmapCacheV2NumCells through the settings struct
directly rather than freerdp_settings_get_uint32(), so the cast and
field access differ slightly from upstream while the security change
(+1ull) is identical.
…5-stable-2.0

[stable-2.0] Backport CVE-2026-29775: [cache,bitmap] overallocate bitmap cache
…4-stable-2.0

[stable-2.0] Backport CVE-2026-24684: [channels,rdpsnd] terminate thread before free
Port the WSLg-specific server-side additions from microsoft/FreeRDP-mirror
working branch (commit a0c6bcd by Hideyuki Nagase, originally based on
FreeRDP 2.4.0) onto current upstream stable-2.0.

Carries:
  * New server-side virtual channel: channels/gfxredir/ (graphics
    redirection PDUs consumed by microsoft/weston-mirror rdp-backend).
  * Public headers: include/freerdp/{channels,server}/gfxredir.h
  * include/freerdp/types.h:   add RECTANGLE_32 (used by gfxredir).
  * config.h.in:               add WITH_CHANNEL_GFXREDIR and the three
                               CHANNEL_GFXREDIR / _CLIENT / _SERVER cmakedefines.
  * channels/server/channels.c: register gfxredir alongside the existing
                                upstream-registered channels.
  * libfreerdp/core/listener.c: replace CreateFileDescriptorEvent with
    WSAEventSelect(FD_READ|FD_ACCEPT|FD_CLOSE) and treat AF_VSOCK peers
    as local (needed for WSLg's HV_SOCK transport between the Linux
    guest and mstsc on the Windows host).

Deliberately NOT carried from a0c6bcd:
  * channels/rdpapplist/ — added in a0c6bcd then removed in 81cfc08
    (mirror PR #1); it now lives in microsoft/wslg.git/rdpapplist as
    an external project consumed by weston-rdp-backend. Skipping both
    commits avoids the net-null add/remove churn.
  * azure-pipelines.yml — stale Microsoft-internal CI from the original
    pipeline (real CI now lives in the wslg-build repo). Not wired up.
  * channels/rdpsnd/server/rdpsnd_main.c additions
    (use_dynamic_virtual_channel + ChannelIdAssigned callback) —
    upstream has incorporated this functionality verbatim since 2.4.0.
  * include/freerdp/server/rdpsnd.h additions — same: upstream now
    declares the field and callback type.
  * include/freerdp/rail.h additions — upstream now exposes the
    TS_RAIL_CLIENTSTATUS_* constants as a typedef enum (and also adds
    TS_RAIL_CLIENTSTATUS_SUPPRESS_ICON_ORDERS which Microsoft's old
    patch lacked).
  * libfreerdp/core/nego.c additions — purely two explanatory comments
    and whitespace; upstream's logic is identical.
  * include/freerdp/update.h offsetOrders field — upstream now exposes
    this as 'size_t offsetOrders' in the same struct; Microsoft's
    'UINT16 offsetOrders' is redundant and would produce a duplicate-
    member compile error. The size_t type from upstream is the correct
    one for the Stream_GetLength/SetPosition consumers in
    libfreerdp/core/update.c.

Also drops Microsoft's original WSACreateEvent();; double-semicolon
typo and over-indented WSAEventSelect call while we are touching the
hunk.

Originally-from: a0c6bcd2c8a0a3a5b88b22d6c40d5d22aac4f1d0
                 "Minor fixes on FreeRDP" by Hideyuki Nagase (Microsoft, 2020-05-30)

Co-authored-by: Hideyuki Nagase <hideyukn@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Hideyuki Nagase <hideyukn@ntdev.microsoft.com>
(cherry picked from commit c574044)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
(cherry picked from commit 18d1e7a)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@benhillis benhillis self-assigned this May 19, 2026
Comment thread libfreerdp/core/rdp.c
winpr_RC4_Free(rdp->rc4_encrypt_key);
rdp->rc4_encrypt_key = NULL;
}
rdp_free_rc4_decrypt_keys(rdp);

for (x = 0; x < ctx->pos; x++)
{
char* msg = str + ctx->pos * sizeof(char*) + x * UNWIND_MAX_LINE_SIZE;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.