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

================= Bug Report (1/1) ==================
## Source: GitHub Advisory
## URL: https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-q5v5-qhj5-mh6m
## Description:
Advisory ID: GHSA-q5v5-qhj5-mh6m
Title: Missing offset validation leading to Out-of-Bounds Read in gdi_multi_opaque_rect

Description:
Summary
Missing offset validation leading to Out Of Bound Read in gdi_multi_opaque_rect
Affected
FreeRDP based clients only. FreeRDP proxy not affected as image decoding is not done by proxy (data passthrough)
Details
FreeRDP/include/freerdp/primary.h
Lines 186 to 196 in 63a2f65
 typedef struct 
 { 
  INT32 nLeftRect; 
  INT32 nTopRect; 
  INT32 nWidth; 
  INT32 nHeight; 
  UINT32 color; 
  UINT32 numRectangles; 
  UINT32 cbData; 
  DELTA_RECT rectangles[45]; 
 } MULTI_OPAQUE_RECT_ORDER; 

The size of the rectangles array is 45.
FreeRDP/libfreerdp/core/orders.c
Lines 1503 to 1504 in 63a2f65
 if (!read_order_field_byte(orderInfo, s, 8, &multi_opaque_rect->numRectangles, TRUE)) 
  return FALSE; 

There is no code to validate if multi_opaque_rect->numRectangles is less than 45.
https://github.com/FreeRDP/FreeRDP/blob/63a2f65618748c12f79ff7450d46c6e194f2db76/libfreerdp/gdi/gdi.c#L723C1-L758
Looping through multi_opaque_rect->numRectangles without proper boundary checks can lead to Out-of-Bounds Read errors.
PoC
Send packet with multi_opaque_rect->numRectangles >= 45
Impact
Out-of-Bounds Read
Asan
==97916==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62200002b7c0 at pc 0x0001013cd838 bp 0x00016fffdc90 sp 0x00016fffdc88
READ of size 4 at 0x62200002b7c0 thread T4
    #0 0x1013cd834 in gdi_multi_opaque_rect+0x3cc (libfreerdp3.3.0.0.dylib:arm64+0x16d834) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #1 0x10148ff08 in update_recv_primary_order+0x195c (libfreerdp3.3.0.0.dylib:arm64+0x22ff08) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #2 0x10148c974 in update_recv_order+0x1cc (libfreerdp3.3.0.0.dylib:arm64+0x22c974) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #3 0x10154423c in update_recv_orders+0x228 (libfreerdp3.3.0.0.dylib:arm64+0x2e423c) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #4 0x101543a68 in update_recv+0x318 (libfreerdp3.3.0.0.dylib:arm64+0x2e3a68) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #5 0x10150bf28 in rdp_recv_data_pdu+0x998 (libfreerdp3.3.0.0.dylib:arm64+0x2abf28) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #6 0x101516fdc in rdp_recv_tpkt_pdu+0x9d8 (libfreerdp3.3.0.0.dylib:arm64+0x2b6fdc) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #7 0x1015165ac in rdp_recv_pdu+0x34 (libfreerdp3.3.0.0.dylib:arm64+0x2b65ac) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #8 0x101511e14 in rdp_recv_callback_int+0x1408 (libfreerdp3.3.0.0.dylib:arm64+0x2b1e14) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #9 0x10151093c in rdp_recv_callback+0x1d8 (libfreerdp3.3.0.0.dylib:arm64+0x2b093c) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #10 0x101537128 in transport_check_fds+0x51c (libfreerdp3.3.0.0.dylib:arm64+0x2d7128) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #11 0x10151271c in rdp_check_fds+0x170 (libfreerdp3.3.0.0.dylib:arm64+0x2b271c) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #12 0x1014ad4f8 in freerdp_check_fds+0x1ac (libfreerdp3.3.0.0.dylib:arm64+0x24d4f8) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #13 0x1014adbc8 in freerdp_check_event_handles+0x70 (libfreerdp3.3.0.0.dylib:arm64+0x24dbc8) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #14 0x100103700 in mac_client_thread+0x5a4 (MacFreeRDP:arm64+0x13700) (BuildId: 648033a131eb3f0f9702f5da3e9b172432000000200000000100000000000d00)
    #15 0x101dcd4ac in thread_launcher thread.c:520
    #16 0x1a20cbfa4 in _pthread_start+0x90 (libsystem_pthread.dylib:arm64+0x6fa4) (BuildId: 46d35233a0513f4fbba4ba56dddc4d1a32000000200000000100000000040d00)
    #17 0x663d8001a20c6d9c  (<unknown module>)

0x62200002b7c0 is located 0 bytes after 5824-byte region [0x62200002a100,0x62200002b7c0)
allocated by thread T0 here:
    #0 0x102355964 in wrap_calloc+0x94 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x51964) (BuildId: 4947f3677e4435f39b5765e7dbc19bf732000000200000000100000000000b00)
    #1 0x10154f91c in update_new+0x28c (libfreerdp3.3.0.0.dylib:arm64+0x2ef91c) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #2 0x101513124 in rdp_new+0x77c (libfreerdp3.3.0.0.dylib:arm64+0x2b3124) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #3 0x1014aefbc in freerdp_context_new_ex+0x254 (libfreerdp3.3.0.0.dylib:arm64+0x24efbc) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00)
    #4 0x1000f5b28 in freerdp_client_context_new+0x29c (MacFreeRDP:arm64+0x5b28) (BuildId: 648033a131eb3f0f9702f5da3e9b172432000000200000000100000000000d00)
    #5 0x100034514 in -[AppDelegate CreateContext]+0x188 (MacFreeRDP:arm64+0x100008514) (BuildId: c0debf5af29834acb3c97ff2be5d5c4932000000200000000100000000000d00)
    #6 0x100032368 in -[AppDelegate applicationDidFinishLaunching:]+0x118 (MacFreeRDP:arm64+0x100006368) (BuildId: c0debf5af29834acb3c97ff2be5d5c4932000000200000000100000000000d00)
    #7 0x1a219f17c in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__+0x90 (CoreFoundation:arm64+0x7417c) (BuildId: 203e44018c2e3157a24b92f52551d43e32000000200000000100000000040d00)
    #8 0xbd1e0001a223aee8  (<unknown module>)
    #9 0xec5e8001a223ae30  (<unknown module>)
    #10 0xce4b0001a21704c8  (<unknown module>)
    #11 0x8e370001a30ce8f0  (<unknown module>)
    #12 0x81240001a53d1154  (<unknown module>)
    #13 0xe83a8001a53d0f04  (<unknown module>)
    #14 0x98108001a53cefa0  (<unknown module>)
    #15 0x5b610001a53ceb9c  (<unknown module>)
    #16 0x242a8001a30f8b60  (<unknown module>)
    #17 0x665d8001a30f89c0  (<unknown module>)
    #18 0xd4670001a84d1514  (<unknown module>)
    #19 0x50320001a84d0e40  (<unknown module>)
    #20 0x32390001a84c9f14  (<unknown module>)
    #21 0x643b0001aba02b40  (<unknown module>)
    #22 0x6c490001a53ca044  (<unknown module>)
    #23 0xde3e0001a53c8edc  (<unknown module>)
    #24 0x774c0001a53bd340  (<unknown module>)
    #25 0x2c3b0001a5394790  (<unknown module>)
    #26 0xe25b800100032020  (<unknown module>)
    #27 0x1a1d73f24  (<unknown module>)
    #28 0xb2377ffffffffffc  (<unknown module>)

Thread T4 created by T0 here:
    #0 0x10234e91c in wrap_pthread_create+0x50 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x4a91c) (BuildId: 4947f3677e4435f39b5765e7dbc19bf732000000200000000100000000000b00)
    #1 0x101dca52c in winpr_StartThread thread.c:568
    #2 0x101dc9c00 in CreateThread thread.c:650
    #3 0x100102e64 in -[MRDPView rdpStart:]+0x964 (MacFreeRDP:arm64+0x12e64) (BuildId: 648033a131eb3f0f9702f5da3e9b172432000000200000000100000000000d00)
    #4 0x1001022b4 in mfreerdp_client_start+0x488 (MacFreeRDP:arm64+0x122b4) (BuildId: 648033a131eb3f0f9702f5da3e9b172432000000200000000100000000000d00)
    #5 0x1000f618c in freerdp_client_start+0x190 (MacFreeRDP:arm64+0x618c) (BuildId: 648033a131eb3f0f9702f5da3e9b172432000000200000000100000000000d00)
    #6 0x10003278c 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 0xbd1e0001a223aee8  (<unknown module>)
    #9 0xec5e8001a223ae30  (<unknown module>)
    #10 0xce4b0001a21704c8  (<unknown module>)
    #11 0x8e370001a30ce8f0  (<unknown module>)
    #12 0x81240001a53d1154  (<unknown module>)
    #13 0xe83a8001a53d0f04  (<unknown module>)
    #14 0x98108001a53cefa0  (<unknown module>)
    #15 0x5b610001a53ceb9c  (<unknown module>)
    #16 0x242a8001a30f8b60  (<unknown module>)
    #17 0x665d8001a30f89c0  (<unknown module>)
    #18 0xd4670001a84d1514  (<unknown module>)
    #19 0x50320001a84d0e40  (<unknown module>)
    #20 0x32390001a84c9f14  (<unknown module>)
    #21 0x643b0001aba02b40  (<unknown module>)
    #22 0x6c490001a53ca044  (<unknown module>)
    #23 0xde3e0001a53c8edc  (<unknown module>)
    #24 0x774c0001a53bd340  (<unknown module>)
    #25 0x2c3b0001a5394790  (<unknown module>)
    #26 0xe25b800100032020  (<unknown module>)
    #27 0x1a1d73f24  (<unknown module>)
    #28 0xb2377ffffffffffc  (<unknown module>)

SUMMARY: AddressSanitizer: heap-buffer-overflow (libfreerdp3.3.0.0.dylib:arm64+0x16d834) (BuildId: a67b59c65b683446b8fc4304a06ccf9b32000000200000000100000000000d00) in gdi_multi_opaque_rect+0x3cc
Shadow bytes around the buggy address:
  0x62200002b500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x62200002b580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x62200002b600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x62200002b680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x62200002b700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x62200002b780: 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa fa fa
  0x62200002b800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x62200002b880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x62200002b900: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x62200002b980: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x62200002ba00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
==97916==ABORTING
[19:51:10:43] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [fatal_handler]: Caught signal 'Abort trap: 6' [6]
[19:51:10:47] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 0: 0   libwinpr3.3.0.0.dylib               0x0000000101d2b6e4 winpr_execinfo_backtrace + 336
[19:51:10:47] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 1: 1   libwinpr3.3.0.0.dylib               0x0000000101d2521c winpr_backtrace + 24
[19:51:10:47] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 2: 2   libwinpr3.3.0.0.dylib               0x0000000101d25578 winpr_log_backtrace_ex + 304
[19:51:10:47] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 3: 3   libwinpr3.3.0.0.dylib               0x0000000101d2543c winpr_log_backtrace + 44
[19:51:10:47] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 4: 4   libfreerdp3.3.0.0.dylib             0x000000010131e1b8 fatal_handler + 460
[19:51:10:47] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 5: 5   libsystem_platform.dylib            0x00000001a20faa24 _sigtramp + 56
[19:51:10:47] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 6: 6   libsystem_pthread.dylib             0x00000001a20cbc28 pthread_kill + 288
[19:51:10:47] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 7: 7   libsystem_c.dylib                   0x00000001a1fd9ae8 abort + 180
[19:51:10:47] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 8: 8   libclang_rt.asan_osx_dynamic.dylib  0x00000001023789b8 _ZN11__sanitizer6AtexitEPFvvE + 0
[19:51:10:47] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 9: 9   libclang_rt.asan_osx_dynamic.dylib  0x0000000102378124 _ZN11__sanitizer22SetCheckUnwindCallbackEPFvvE + 0
[19:51:10:47] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 10: 10  libclang_rt.asan_osx_dynamic.dylib  0x000000010235d658 _ZN6__asan16ErrorDescription5PrintEv + 0
[19:51:10:47] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 11: 11  libclang_rt.asan_osx_dynamic.dylib  0x000000010235c99c _ZN6__asan18ReportGenericErrorEmmmmbmjb + 1452
[19:51:10:48] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 12: 12  libclang_rt.asan_osx_dynamic.dylib  0x000000010235dba0 __asan_report_load4 + 52
[19:51:10:48] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 13: 13  libfreerdp3.3.0.0.dylib             0x00000001013cd838 gdi_multi_opaque_rect + 976
[19:51:10:48] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 14: 14  libfreerdp3.3.0.0.dylib             0x000000010148ff0c update_recv_primary_order + 6496
[19:51:10:48] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 15: 15  libfreerdp3.3.0.0.dylib             0x000000010148c978 update_recv_order + 464
[19:51:10:48] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 16: 16  libfreerdp3.3.0.0.dylib             0x0000000101544240 update_recv_orders + 556
[19:51:10:48] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 17: 17  libfreerdp3.3.0.0.dylib             0x0000000101543a6c update_recv + 796
[19:51:10:48] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 18: 18  libfreerdp3.3.0.0.dylib             0x000000010150bf2c rdp_recv_data_pdu + 2460
[19:51:10:48] [97916:6ffff000] [ERROR][com.freerdp.utils.signal] - [winpr_log_backtrace_ex]: 19: 19  libfreerdp3.3.0.0.dylib             0x0000000101516fe0 rdp_recv_tpkt_pdu + 2524


References:
https://github.com/FreeRDP/FreeRDP/blob/63a2f65618748c12f79ff7450d46c6e194f2db76/include/freerdp/primary.h#L186-L196
https://github.com/FreeRDP/FreeRDP/commit/63a2f65618748c12f79ff7450d46c6e194f2db76
https://github.com/FreeRDP/FreeRDP/blob/63a2f65618748c12f79ff7450d46c6e194f2db76/libfreerdp/core/orders.c#L1503-L1504
https://github.com/FreeRDP/FreeRDP/blob/63a2f65618748c12f79ff7450d46c6e194f2db76/libfreerdp/gdi/gdi.c#L723C1-L758

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: