Project: freerdp (freerdp/freerdp), language: c++
Vulnerability instance: freerdp.cve-2023-40576
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Advisory
## URL: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-x3x5-r7jm-5pq2
## Description:
Advisory ID: GHSA-x3x5-r7jm-5pq2
Title: Out-Of-Bounds Read in RleDecompress

Description:
Summary
Out-Of-Bounds Read in RleDecompress
Affected
FreeRDP based clients only. FreeRDP proxy not affected as image decoding is not done by proxy (data passthrough)
Details
FreeRDP/libfreerdp/codec/include/bitmap.c
Lines 94 to 113 in 5be5553
 static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BYTE* pbDestBuffer, 
                                  UINT32 rowDelta, UINT32 width, UINT32 height) 
 { 
 #if defined(WITH_DEBUG_CODECS) 
  char sbuffer[128] = { 0 }; 
 #endif 
  const BYTE* pbSrc = pbSrcBuffer; 
  const BYTE* pbEnd; 
  const BYTE* pbDestEnd; 
  BYTE* pbDest = pbDestBuffer; 
  PIXEL temp; 
  PIXEL fgPel = WHITE_PIXEL; 
  BOOL fInsertFgPel = FALSE; 
  BOOL fFirstLine = TRUE; 
  BYTE bitmask; 
  PIXEL pixelA, pixelB; 
  UINT32 runLength; 
  UINT32 code; 
  UINT32 advance = 0; 
  RLEEXTRA 

In the RleDecompress, Out-Of-Bounds Read occurs because it processes in without checking if it contains data of sufficient length.
PoC
Insufficient data for pbSrcBuffer may cause errors or crashes.
Impact
Out-Of-Bounds Read
Asan
==93486==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000f7897 at pc 0x0001012c6c94 bp 0x0001700b5c10 sp 0x0001700b5c08
READ of size 1 at 0x6020000f7897 thread T4
    #0 0x1012c6c90 in RleDecompress24to24+0x19b8 (libfreerdp3.3.0.0.dylib:arm64+0x92c90) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #1 0x1012c4e54 in interleaved_decompress+0x4b4 (libfreerdp3.3.0.0.dylib:arm64+0x90e54) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #2 0x1013863a8 in gdi_Bitmap_Decompress+0xae8 (libfreerdp3.3.0.0.dylib:arm64+0x1523a8) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #3 0x10139c5b0 in gdi_bitmap_update+0x630 (libfreerdp3.3.0.0.dylib:arm64+0x1685b0) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #4 0x101517b80 in update_recv+0x430 (libfreerdp3.3.0.0.dylib:arm64+0x2e3b80) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #5 0x1014dff28 in rdp_recv_data_pdu+0x998 (libfreerdp3.3.0.0.dylib:arm64+0x2abf28) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #6 0x1014eafdc in rdp_recv_tpkt_pdu+0x9d8 (libfreerdp3.3.0.0.dylib:arm64+0x2b6fdc) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #7 0x1014ea5ac in rdp_recv_pdu+0x34 (libfreerdp3.3.0.0.dylib:arm64+0x2b65ac) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #8 0x1014e5e14 in rdp_recv_callback_int+0x1408 (libfreerdp3.3.0.0.dylib:arm64+0x2b1e14) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #9 0x1014e493c in rdp_recv_callback+0x1d8 (libfreerdp3.3.0.0.dylib:arm64+0x2b093c) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #10 0x10150b128 in transport_check_fds+0x51c (libfreerdp3.3.0.0.dylib:arm64+0x2d7128) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #11 0x1014e671c in rdp_check_fds+0x170 (libfreerdp3.3.0.0.dylib:arm64+0x2b271c) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #12 0x1014814f8 in freerdp_check_fds+0x1ac (libfreerdp3.3.0.0.dylib:arm64+0x24d4f8) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #13 0x101481bc8 in freerdp_check_event_handles+0x70 (libfreerdp3.3.0.0.dylib:arm64+0x24dbc8) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #14 0x1000d7700 in mac_client_thread+0x5a4 (MacFreeRDP:arm64+0x13700) (BuildId: 648033a131eb3f0f9702f5da3e9b172432000000200000000100000000000d00)
    #15 0x101da14ac in thread_launcher thread.c:520
    #16 0x1a20cbfa4 in _pthread_start+0x90 (libsystem_pthread.dylib:arm64+0x6fa4) (BuildId: 46d35233a0513f4fbba4ba56dddc4d1a32000000200000000100000000040d00)
    #17 0xbf168001a20c6d9c  (<unknown module>)

0x6020000f7897 is located 0 bytes after 7-byte region [0x6020000f7890,0x6020000f7897)
allocated by thread T4 here:
    #0 0x1023295b0 in wrap_malloc+0x8c (libclang_rt.asan_osx_dynamic.dylib:arm64+0x515b0) (BuildId: 4947f3677e4435f39b5765e7dbc19bf732000000200000000100000000000b00)
    #1 0x101511e6c in update_read_bitmap_data+0x18c8 (libfreerdp3.3.0.0.dylib:arm64+0x2dde6c) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #2 0x101510220 in update_read_bitmap_update+0x418 (libfreerdp3.3.0.0.dylib:arm64+0x2dc220) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #3 0x101517a7c in update_recv+0x32c (libfreerdp3.3.0.0.dylib:arm64+0x2e3a7c) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #4 0x1014dff28 in rdp_recv_data_pdu+0x998 (libfreerdp3.3.0.0.dylib:arm64+0x2abf28) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #5 0x1014eafdc in rdp_recv_tpkt_pdu+0x9d8 (libfreerdp3.3.0.0.dylib:arm64+0x2b6fdc) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #6 0x1014ea5ac in rdp_recv_pdu+0x34 (libfreerdp3.3.0.0.dylib:arm64+0x2b65ac) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #7 0x1014e5e14 in rdp_recv_callback_int+0x1408 (libfreerdp3.3.0.0.dylib:arm64+0x2b1e14) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #8 0x1014e493c in rdp_recv_callback+0x1d8 (libfreerdp3.3.0.0.dylib:arm64+0x2b093c) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #9 0x10150b128 in transport_check_fds+0x51c (libfreerdp3.3.0.0.dylib:arm64+0x2d7128) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #10 0x1014e671c in rdp_check_fds+0x170 (libfreerdp3.3.0.0.dylib:arm64+0x2b271c) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #11 0x1014814f8 in freerdp_check_fds+0x1ac (libfreerdp3.3.0.0.dylib:arm64+0x24d4f8) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #12 0x101481bc8 in freerdp_check_event_handles+0x70 (libfreerdp3.3.0.0.dylib:arm64+0x24dbc8) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #13 0x1000d7700 in mac_client_thread+0x5a4 (MacFreeRDP:arm64+0x13700) (BuildId: 648033a131eb3f0f9702f5da3e9b172432000000200000000100000000000d00)
    #14 0x101da14ac in thread_launcher thread.c:520
    #15 0x1a20cbfa4 in _pthread_start+0x90 (libsystem_pthread.dylib:arm64+0x6fa4) (BuildId: 46d35233a0513f4fbba4ba56dddc4d1a32000000200000000100000000040d00)
    #16 0xbf168001a20c6d9c  (<unknown module>)

Thread T4 created by T0 here:
    #0 0x10232291c in wrap_pthread_create+0x50 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x4a91c) (BuildId: 4947f3677e4435f39b5765e7dbc19bf732000000200000000100000000000b00)
    #1 0x101d9e52c in winpr_StartThread thread.c:568
    #2 0x101d9dc00 in CreateThread thread.c:650
    #3 0x1000d6e64 in -[MRDPView rdpStart:]+0x964 (MacFreeRDP:arm64+0x12e64) (BuildId: 648033a131eb3f0f9702f5da3e9b172432000000200000000100000000000d00)
    #4 0x1000d62b4 in mfreerdp_client_start+0x488 (MacFreeRDP:arm64+0x122b4) (BuildId: 648033a131eb3f0f9702f5da3e9b172432000000200000000100000000000d00)
    #5 0x1000ca18c in freerdp_client_start+0x190 (MacFreeRDP:arm64+0x618c) (BuildId: 648033a131eb3f0f9702f5da3e9b172432000000200000000100000000000d00)
    #6 0x10000678c in -[AppDelegate applicationDidFinishLaunching:]+0x53c (MacFreeRDP:arm64+0x10000678c) (BuildId: c0debf5af29834acb3c97ff2be5d5c4932000000200000000100000000000d00)
    #7 0x1a219f17c in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__+0x90 (CoreFoundation:arm64+0x7417c) (BuildId: 203e44018c2e3157a24b92f52551d43e32000000200000000100000000040d00)
    #8 0x4b7b8001a223aee8  (<unknown module>)
    #9 0xf3128001a223ae30  (<unknown module>)
    #10 0x22678001a21704c8  (<unknown module>)
    #11 0xcd240001a30ce8f0  (<unknown module>)
    #12 0x824a0001a53d1154  (<unknown module>)
    #13 0x88280001a53d0f04  (<unknown module>)
    #14 0x52750001a53cefa0  (<unknown module>)
    #15 0x8a3e8001a53ceb9c  (<unknown module>)
    #16 0x10278001a30f8b60  (<unknown module>)
    #17 0x351a8001a30f89c0  (<unknown module>)
    #18 0xf24d8001a84d1514  (<unknown module>)
    #19 0xa4660001a84d0e40  (<unknown module>)
    #20 0xf060001a84c9f14  (<unknown module>)
    #21 0xec3d8001aba02b40  (<unknown module>)
    #22 0x976b8001a53ca044  (<unknown module>)
    #23 0x1e320001a53c8edc  (<unknown module>)
    #24 0xe258001a53bd340  (<unknown module>)
    #25 0xf8370001a5394790  (<unknown module>)
    #26 0x4e24800100006020  (<unknown module>)
    #27 0x1a1d73f24  (<unknown module>)
    #28 0xa13efffffffffffc  (<unknown module>)

SUMMARY: AddressSanitizer: heap-buffer-overflow (libfreerdp3.3.0.0.dylib:arm64+0x92c90) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00) in RleDecompress24to24+0x19b8
Shadow bytes around the buggy address:
  0x6020000f7600: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x6020000f7680: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x6020000f7700: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x6020000f7780: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x6020000f7800: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
=>0x6020000f7880: fa fa[07]fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x6020000f7900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x6020000f7980: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x6020000f7a00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x6020000f7a80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x6020000f7b00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb


References:
https://github.com/FreeRDP/FreeRDP/blob/5be5553e0da72178a4b94cc1ffbdace9ceb153e5/libfreerdp/codec/include/bitmap.c#L94-L113
https://github.com/FreeRDP/FreeRDP/commit/5be5553e0da72178a4b94cc1ffbdace9ceb153e5

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
    -DCMAKE_C_FLAGS="${CFLAGS}"
    -DCMAKE_CXX_FLAGS="${CXXFLAGS}"
    -DCMAKE_EXE_LINKER_FLAGS="${LDFLAGS}"
    -DCMAKE_MODULE_LINKER_FLAGS="${LDFLAGS}"
    -DCMAKE_SHARED_LINKER_FLAGS="${LDFLAGS}"
cmake "${cmake_args[@]}" -S . -B build -G Ninja
cmake --build build --parallel --target fuzzers

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y build-essential git-core cmake ninja-build pkg-config zlib1g-dev libx11-dev libxext-dev libxinerama-dev libxcursor-dev libxkbfile-dev libxv-dev libxi-dev libxdamage-dev libxrender-dev libxrandr-dev libssl-dev libasound2-dev libcups2-dev libpulse-dev libcairo2-dev libavutil-dev libavcodec-dev libusb-1.0-0-dev libicu-dev
RUN git clone https://github.com/freerdp/freerdp freerdp
RUN git -C freerdp checkout f468a06d88c55b9ed484757326a9528cf27d33f4
WORKDIR $SRC/freerdp
COPY build.sh $SRC/

Additional files: