Description
When using IronRDP as a client to connect to xRDP servers, two related issues occur in ironrdp-session:
- Diagonal bitmap distortion — The rendered desktop appears as diagonally-shifted pixel rows, making the display unusable.
- Panic on out-of-bounds framebuffer writes —
index out of bounds panics occur during bitmap updates, particularly near framebuffer edges or during resolution changes.
Both issues are specific to the slow-path bitmap update code path (fast_path.rs bitmap handling + image.rs apply methods). RFX/progressive codec updates are unaffected.
Root Cause
1. Bitmap stride mismatch in fast_path.rs
xRDP (and other servers) commonly send BitmapData updates where the bitmap data dimensions (bitmapWidth × bitmapHeight) differ from the destination rectangle dimensions (destRight - destLeft + 1 × destBottom - destTop + 1). Per MS-RDPBCGR §2.2.9.1.1.3.1.2.2, these are distinct fields:
bitmapWidth / bitmapHeight: dimensions of the bitmap data (may include padding for alignment)
destLeft / destTop / destRight / destBottom: destination rectangle on the framebuffer
Currently, update.rectangle (derived from the dest fields) is passed directly to the apply_* methods, which use the rectangle's width as the row stride for iterating over pixel data. When the bitmap data width differs from the rectangle width, pixels are read at incorrect offsets, producing a diagonal shearing artifact.
2. Missing bounds checks in image.rs
Multiple apply_* methods (apply_rgb16_bitmap, apply_rgb15_bitmap, apply_bgr24_bitmap, apply_rgb8_with_palette, apply_rgb24_iter, apply_rgb32_bitmap) compute dst_idx from the update rectangle coordinates and write directly to self.data[dst_idx..] without verifying that dst_idx is within self.data.len(). When xRDP sends bitmap updates that extend beyond the framebuffer boundary (common during session startup or resize), this causes:
panicked at ironrdp-session/src/image.rs:784:30: index out of bounds: the len is 8294400 but the index is 8300760
Reproduction
- Set up an xRDP server (e.g., on Ubuntu with
xrdp + xfce4-session)
- Connect using any IronRDP-based client
- Observe diagonal distortion on the login screen and subsequent desktop
- Occasionally observe panics during initial bitmap updates
Tested with xRDP 0.10.x on Ubuntu 22.04, IronRDP at commit 3fe6d15.
Environment
- IronRDP version:
3fe6d15 (master)
- RDP Server: xRDP 0.10.x (Ubuntu 22.04)
- Client platform: WASM (wasm32-unknown-unknown) via
ironrdp-session
- Color depths affected: 8bpp, 15bpp, 16bpp, 24bpp, 32bpp (all slow-path bitmap paths)
Proposed Fix
Fix bitmap stride mismatch and out-of-bounds writes for xRDP compatibility #1252
Description
When using IronRDP as a client to connect to xRDP servers, two related issues occur in
ironrdp-session:index out of boundspanics occur during bitmap updates, particularly near framebuffer edges or during resolution changes.Both issues are specific to the slow-path bitmap update code path (
fast_path.rsbitmap handling +image.rsapply methods). RFX/progressive codec updates are unaffected.Root Cause
1. Bitmap stride mismatch in
fast_path.rsxRDP (and other servers) commonly send
BitmapDataupdates where the bitmap data dimensions (bitmapWidth×bitmapHeight) differ from the destination rectangle dimensions (destRight - destLeft + 1×destBottom - destTop + 1). Per MS-RDPBCGR §2.2.9.1.1.3.1.2.2, these are distinct fields:bitmapWidth/bitmapHeight: dimensions of the bitmap data (may include padding for alignment)destLeft/destTop/destRight/destBottom: destination rectangle on the framebufferCurrently,
update.rectangle(derived from the dest fields) is passed directly to theapply_*methods, which use the rectangle's width as the row stride for iterating over pixel data. When the bitmap data width differs from the rectangle width, pixels are read at incorrect offsets, producing a diagonal shearing artifact.2. Missing bounds checks in
image.rsMultiple
apply_*methods (apply_rgb16_bitmap,apply_rgb15_bitmap,apply_bgr24_bitmap,apply_rgb8_with_palette,apply_rgb24_iter,apply_rgb32_bitmap) computedst_idxfrom the update rectangle coordinates and write directly toself.data[dst_idx..]without verifying thatdst_idxis withinself.data.len(). When xRDP sends bitmap updates that extend beyond the framebuffer boundary (common during session startup or resize), this causes:panicked at ironrdp-session/src/image.rs:784:30: index out of bounds: the len is 8294400 but the index is 8300760Reproduction
xrdp+xfce4-session)Tested with xRDP 0.10.x on Ubuntu 22.04, IronRDP at commit 3fe6d15.
Environment
3fe6d15(master)ironrdp-sessionProposed Fix
Fix bitmap stride mismatch and out-of-bounds writes for xRDP compatibility #1252