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

================= Bug Report (1/1) ==================
## Source: GitHub Advisory
## URL: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-9w28-wwj5-p4xq
## Description:
Advisory ID: GHSA-9w28-wwj5-p4xq
Title: Out-Of-Bounds Read in general_LumaToYUV444

Description:
Summary
Out-Of-Bounds Read in general_LumaToYUV444
Affected
FreeRDP based clients only. FreeRDP proxy not affected as image decoding is not done by proxy (data passthrough)
Details
FreeRDP/libfreerdp/codec/nsc.c
Lines 115 to 175 in 5be5553
 static BOOL nsc_rle_decode(BYTE* in, BYTE* out, UINT32 outSize, UINT32 originalSize) 
 { 
  UINT32 left = originalSize; 
     while (left > 4) 
  { 
   const BYTE value = *in++; 
   UINT32 len = 0; 
      if (left == 5) 
   { 
    if (outSize < 1) 
     return FALSE; 
       outSize--; 
    *out++ = value; 
    left--; 
   } 
   else if (value == *in) 
   { 
    in++; 
       if (*in < 0xFF) 
    { 
     len = (UINT32)*in++; 
     len += 2; 
    } 
    else 
    { 
     in++; 
     len = ((UINT32)(*in++)); 
     len |= ((UINT32)(*in++)) << 8U; 
     len |= ((UINT32)(*in++)) << 16U; 
     len |= ((UINT32)(*in++)) << 24U; 
    } 
       if (outSize < len) 
     return FALSE; 
       outSize -= len; 
    FillMemory(out, len, value); 
    out += len; 
    left -= len; 
   } 
   else 
   { 
    if (outSize < 1) 
     return FALSE; 
       outSize--; 
    *out++ = value; 
    left--; 
   } 
  } 
     if ((outSize < 4) || (left < 4)) 
   return FALSE; 
     memcpy(out, in, 4); 
  return TRUE; 
 } 

In the general_LumaToYUV444function, Out-Of-Bounds Read occurs because it processes in without checking if it contains data of sufficient length.
PoC
Insufficient data for in may cause errors or crashes.
Impact
Out-Of-Bounds Read
Asan
==27284==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62d000b164a9 at pc 0x000103b3b238 bp 0x00016d73d2b0 sp 0x00016d73d2a8
READ of size 1 at 0x62d000b164a9 thread T4
    #0 0x103b3b234 in nsc_rle_decode+0x140 (libfreerdp3.3.0.0.dylib:arm64+0x1f234) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #1 0x103b3a5d8 in nsc_rle_decompress_data+0x500 (libfreerdp3.3.0.0.dylib:arm64+0x1e5d8) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #2 0x103b39494 in nsc_process_message+0x494 (libfreerdp3.3.0.0.dylib:arm64+0x1d494) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #3 0x103b76690 in clear_decompress_nscodec+0xf0 (libfreerdp3.3.0.0.dylib:arm64+0x5a690) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #4 0x103b75190 in clear_decompress_subcodecs_data+0x1008 (libfreerdp3.3.0.0.dylib:arm64+0x59190) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #5 0x103b6f7c4 in clear_decompress+0x11a0 (libfreerdp3.3.0.0.dylib:arm64+0x537c4) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #6 0x103c7c160 in gdi_SurfaceCommand_ClearCodec+0x6fc (libfreerdp3.3.0.0.dylib:arm64+0x160160) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #7 0x103c734e0 in gdi_SurfaceCommand+0x564 (libfreerdp3.3.0.0.dylib:arm64+0x1574e0) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #8 0x102e52118 in rdpgfx_decode+0x288 (libfreerdp-client3.3.0.0.dylib:arm64+0xaa118) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #9 0x102e3bafc in rdpgfx_recv_wire_to_surface_1_pdu+0x1760 (libfreerdp-client3.3.0.0.dylib:arm64+0x93afc) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #10 0x102e390e4 in rdpgfx_recv_pdu+0x5d4 (libfreerdp-client3.3.0.0.dylib:arm64+0x910e4) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #11 0x102e37fd4 in rdpgfx_on_data_received+0x448 (libfreerdp-client3.3.0.0.dylib:arm64+0x8ffd4) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #12 0x102dbb428 in dvcman_call_on_receive+0x164 (libfreerdp-client3.3.0.0.dylib:arm64+0x13428) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #13 0x102dbb218 in dvcman_receive_channel_data+0x3c4 (libfreerdp-client3.3.0.0.dylib:arm64+0x13218) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #14 0x102db7c7c in drdynvc_process_data+0x2c8 (libfreerdp-client3.3.0.0.dylib:arm64+0xfc7c) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #15 0x102db5ef0 in drdynvc_order_recv+0x334 (libfreerdp-client3.3.0.0.dylib:arm64+0xdef0) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #16 0x102db5934 in drdynvc_virtual_channel_event_data_received+0x498 (libfreerdp-client3.3.0.0.dylib:arm64+0xd934) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #17 0x102db461c in drdynvc_virtual_channel_open_event_ex+0x1ac (libfreerdp-client3.3.0.0.dylib:arm64+0xc61c) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #18 0x103d73258 in freerdp_channels_data+0x5cc (libfreerdp3.3.0.0.dylib:arm64+0x257258) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #19 0x103e24c24 in freerdp_channel_process+0x6e0 (libfreerdp3.3.0.0.dylib:arm64+0x308c24) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #20 0x103dd4d0c in rdp_recv_tpkt_pdu+0x11e8 (libfreerdp3.3.0.0.dylib:arm64+0x2b8d0c) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #21 0x103dd3acc in rdp_recv_pdu+0x34 (libfreerdp3.3.0.0.dylib:arm64+0x2b7acc) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #22 0x103dcf334 in rdp_recv_callback_int+0x1408 (libfreerdp3.3.0.0.dylib:arm64+0x2b3334) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #23 0x103dcde5c in rdp_recv_callback+0x1d8 (libfreerdp3.3.0.0.dylib:arm64+0x2b1e5c) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #24 0x103df4648 in transport_check_fds+0x51c (libfreerdp3.3.0.0.dylib:arm64+0x2d8648) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #25 0x103dcfc3c in rdp_check_fds+0x170 (libfreerdp3.3.0.0.dylib:arm64+0x2b3c3c) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #26 0x103d6aa14 in freerdp_check_fds+0x1ac (libfreerdp3.3.0.0.dylib:arm64+0x24ea14) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #27 0x103d6b0e4 in freerdp_check_event_handles+0x70 (libfreerdp3.3.0.0.dylib:arm64+0x24f0e4) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #28 0x1029c3130 in mac_client_thread+0x5a4 (MacFreeRDP:arm64+0x13130) (BuildId: 3a4e43fe04f43036ab9335815490e83b32000000200000000100000000000d00)
    #29 0x1046814ac in thread_launcher thread.c:520
    #30 0x192413fa4 in _pthread_start+0x90 (libsystem_pthread.dylib:arm64+0x6fa4) (BuildId: 46d35233a0513f4fbba4ba56dddc4d1a32000000200000000100000000040d00)
    #31 0x822280019240ed9c  (<unknown module>)

0x62d000b164a9 is located 0 bytes after 32937-byte region [0x62d000b0e400,0x62d000b164a9)
allocated by thread T4 here:
    #0 0x104c095b0 in wrap_malloc+0x8c (libclang_rt.asan_osx_dynamic.dylib:arm64+0x515b0) (BuildId: 4947f3677e4435f39b5765e7dbc19bf732000000200000000100000000000b00)
    #1 0x103b441d4 in aligned_zgfx_malloc+0x18 (libfreerdp3.3.0.0.dylib:arm64+0x281d4) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #2 0x103b41dd4 in zgfx_decompress+0x4ac (libfreerdp3.3.0.0.dylib:arm64+0x25dd4) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #3 0x102e37dbc in rdpgfx_on_data_received+0x230 (libfreerdp-client3.3.0.0.dylib:arm64+0x8fdbc) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #4 0x102dbb428 in dvcman_call_on_receive+0x164 (libfreerdp-client3.3.0.0.dylib:arm64+0x13428) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #5 0x102dbb218 in dvcman_receive_channel_data+0x3c4 (libfreerdp-client3.3.0.0.dylib:arm64+0x13218) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #6 0x102db7c7c in drdynvc_process_data+0x2c8 (libfreerdp-client3.3.0.0.dylib:arm64+0xfc7c) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #7 0x102db5ef0 in drdynvc_order_recv+0x334 (libfreerdp-client3.3.0.0.dylib:arm64+0xdef0) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #8 0x102db5934 in drdynvc_virtual_channel_event_data_received+0x498 (libfreerdp-client3.3.0.0.dylib:arm64+0xd934) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #9 0x102db461c in drdynvc_virtual_channel_open_event_ex+0x1ac (libfreerdp-client3.3.0.0.dylib:arm64+0xc61c) (BuildId: 776adf67bfdc356180bc0f4db402691032000000200000000100000000000d00)
    #10 0x103d73258 in freerdp_channels_data+0x5cc (libfreerdp3.3.0.0.dylib:arm64+0x257258) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #11 0x103e24c24 in freerdp_channel_process+0x6e0 (libfreerdp3.3.0.0.dylib:arm64+0x308c24) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #12 0x103dd4d0c in rdp_recv_tpkt_pdu+0x11e8 (libfreerdp3.3.0.0.dylib:arm64+0x2b8d0c) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #13 0x103dd3acc in rdp_recv_pdu+0x34 (libfreerdp3.3.0.0.dylib:arm64+0x2b7acc) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #14 0x103dcf334 in rdp_recv_callback_int+0x1408 (libfreerdp3.3.0.0.dylib:arm64+0x2b3334) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #15 0x103dcde5c in rdp_recv_callback+0x1d8 (libfreerdp3.3.0.0.dylib:arm64+0x2b1e5c) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #16 0x103df4648 in transport_check_fds+0x51c (libfreerdp3.3.0.0.dylib:arm64+0x2d8648) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #17 0x103dcfc3c in rdp_check_fds+0x170 (libfreerdp3.3.0.0.dylib:arm64+0x2b3c3c) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #18 0x103d6aa14 in freerdp_check_fds+0x1ac (libfreerdp3.3.0.0.dylib:arm64+0x24ea14) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #19 0x103d6b0e4 in freerdp_check_event_handles+0x70 (libfreerdp3.3.0.0.dylib:arm64+0x24f0e4) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00)
    #20 0x1029c3130 in mac_client_thread+0x5a4 (MacFreeRDP:arm64+0x13130) (BuildId: 3a4e43fe04f43036ab9335815490e83b32000000200000000100000000000d00)
    #21 0x1046814ac in thread_launcher thread.c:520
    #22 0x192413fa4 in _pthread_start+0x90 (libsystem_pthread.dylib:arm64+0x6fa4) (BuildId: 46d35233a0513f4fbba4ba56dddc4d1a32000000200000000100000000040d00)
    #23 0x822280019240ed9c  (<unknown module>)

Thread T4 created by T0 here:
    #0 0x104c0291c in wrap_pthread_create+0x50 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x4a91c) (BuildId: 4947f3677e4435f39b5765e7dbc19bf732000000200000000100000000000b00)
    #1 0x10467e52c in winpr_StartThread thread.c:568
    #2 0x10467dc00 in CreateThread thread.c:650
    #3 0x1029c2894 in -[MRDPView rdpStart:]+0x964 (MacFreeRDP:arm64+0x12894) (BuildId: 3a4e43fe04f43036ab9335815490e83b32000000200000000100000000000d00)
    #4 0x1029c1ce4 in mfreerdp_client_start+0x488 (MacFreeRDP:arm64+0x11ce4) (BuildId: 3a4e43fe04f43036ab9335815490e83b32000000200000000100000000000d00)
    #5 0x1029b5bbc in freerdp_client_start+0x190 (MacFreeRDP:arm64+0x5bbc) (BuildId: 3a4e43fe04f43036ab9335815490e83b32000000200000000100000000000d00)
    #6 0x1028f278c in -[AppDelegate applicationDidFinishLaunching:]+0x53c (MacFreeRDP:arm64+0x10000678c) (BuildId: c0debf5af29834acb3c97ff2be5d5c4932000000200000000100000000000d00)
    #7 0x1924e717c in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__+0x90 (CoreFoundation:arm64+0x7417c) (BuildId: 203e44018c2e3157a24b92f52551d43e32000000200000000100000000040d00)
    #8 0x1279000192582ee8  (<unknown module>)
    #9 0x511c000192582e30  (<unknown module>)
    #10 0x29328001924b84c8  (<unknown module>)
    #11 0x9a4f0001934168f0  (<unknown module>)
    #12 0xa749000195719154  (<unknown module>)
    #13 0x6c25000195718f04  (<unknown module>)
    #14 0x1d61000195716fa0  (<unknown module>)
    #15 0xec4a800195716b9c  (<unknown module>)
    #16 0x6a2a000193440b60  (<unknown module>)
    #17 0x4f750001934409c0  (<unknown module>)
    #18 0x511800198819514  (<unknown module>)
    #19 0x343b000198818e40  (<unknown module>)
    #20 0xe303000198811f14  (<unknown module>)
    #21 0x746980019bd4ab40  (<unknown module>)
    #22 0xbe4d800195712044  (<unknown module>)
    #23 0xb366000195710edc  (<unknown module>)
    #24 0x672000195705340  (<unknown module>)
    #25 0xd21f8001956dc790  (<unknown module>)
    #26 0xf7240001028f2020  (<unknown module>)
    #27 0x1920bbf24  (<unknown module>)
    #28 0xfa51fffffffffffc  (<unknown module>)

SUMMARY: AddressSanitizer: heap-buffer-overflow (libfreerdp3.3.0.0.dylib:arm64+0x1f234) (BuildId: c10fdfc3bbf03bcab7ef4b235ff1e76b32000000200000000100000000000d00) in nsc_rle_decode+0x140
Shadow bytes around the buggy address:
  0x62d000b16200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x62d000b16280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x62d000b16300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x62d000b16380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x62d000b16400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x62d000b16480: 00 00 00 00 00[01]fa fa fa fa fa fa fa fa fa fa
  0x62d000b16500: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x62d000b16580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x62d000b16600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x62d000b16680: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x62d000b16700: 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/nsc.c#L115-L175
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 ccache 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 libpkcs11-helper1-dev libpkcs11-helper1 libsdl2-ttf-dev libwayland-dev libpam0g-dev libxcb-damage0-dev ccache libxtst-dev libfuse-dev libsystemd-dev libsoxr-dev libsdl2-dev docbook-xsl libkrb5-dev krb5-multidev libcjson-dev libswscale-dev libswresample-dev libpcsclite-dev xsltproc libsdl2-dev
RUN git clone https://github.com/freerdp/freerdp freerdp
RUN git -C freerdp checkout 16047bd16f159ee4aea581854170e83c36862793
WORKDIR $SRC/freerdp
COPY build.sh $SRC/

Additional files: