diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:25:36 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:25:36 +0000 |
commit | 8050c230ded858d59518fce751e28713dd4266f9 (patch) | |
tree | 3b2835ad0af9b436b7ae77963fc10735adc13d25 /libfreerdp/core | |
parent | Adding upstream version 3.5.0+dfsg1. (diff) | |
download | freerdp3-upstream.tar.xz freerdp3-upstream.zip |
Adding upstream version 3.5.1+dfsg1.upstream/3.5.1+dfsg1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libfreerdp/core')
-rw-r--r-- | libfreerdp/core/aad.c | 4 | ||||
-rw-r--r-- | libfreerdp/core/gcc.c | 5 | ||||
-rw-r--r-- | libfreerdp/core/info.c | 4 | ||||
-rw-r--r-- | libfreerdp/core/orders.c | 16 | ||||
-rw-r--r-- | libfreerdp/core/peer.c | 1 | ||||
-rw-r--r-- | libfreerdp/core/redirection.c | 2 | ||||
-rw-r--r-- | libfreerdp/core/test/CMakeLists.txt | 7 | ||||
-rw-r--r-- | libfreerdp/core/test/TestFuzzCoreClient.c | 116 | ||||
-rw-r--r-- | libfreerdp/core/test/TestFuzzCoreServer.c | 108 | ||||
-rw-r--r-- | libfreerdp/core/update.c | 11 |
10 files changed, 261 insertions, 13 deletions
diff --git a/libfreerdp/core/aad.c b/libfreerdp/core/aad.c index 15eabed..00593a0 100644 --- a/libfreerdp/core/aad.c +++ b/libfreerdp/core/aad.c @@ -716,11 +716,11 @@ static char* bn_to_base64_url(wLog* wlog, rdpPrivateKey* key, enum FREERDP_KEY_P WINPR_ASSERT(key); size_t len = 0; - char* bn = freerdp_key_get_param(key, param, &len); + BYTE* bn = freerdp_key_get_param(key, param, &len); if (!bn) return NULL; - char* b64 = (char*)crypto_base64url_encode(bn, len); + char* b64 = crypto_base64url_encode(bn, len); free(bn); if (!b64) diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index 733a763..f2d035a 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -1765,6 +1765,9 @@ static BOOL gcc_update_server_random(rdpSettings* settings) */ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) { + if (!gcc_update_server_random(mcs_get_settings(mcs))) + return FALSE; + const rdpSettings* settings = mcs_get_const_settings(mcs); WINPR_ASSERT(s); @@ -1779,8 +1782,6 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE) return TRUE; - if (!gcc_update_server_random(settings)) - return FALSE; if (!Stream_EnsureRemainingCapacity(s, sizeof(UINT32) + settings->ServerRandomLength)) return FALSE; diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 7d6eec1..3395e4d 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -1398,6 +1398,10 @@ static BOOL rdp_write_logon_info_v1(wStream* s, logon_info* info) return FALSE; /* domain */ + WINPR_ASSERT(info); + if (!info->domain || !info->username) + return FALSE; + len = strnlen(info->domain, charLen + 1); if (len > charLen) return FALSE; diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index 855b700..bef1b45 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -797,9 +797,11 @@ static INLINE BOOL update_write_4byte_unsigned(wStream* s, UINT32 value) return TRUE; } + static INLINE BOOL update_read_delta(wStream* s, INT32* value) { BYTE byte = 0; + UINT32 uvalue = 0; if (!Stream_CheckAndLogRequiredLength(TAG, s, 1)) return FALSE; @@ -807,9 +809,9 @@ static INLINE BOOL update_read_delta(wStream* s, INT32* value) Stream_Read_UINT8(s, byte); if (byte & 0x40) - *value = (byte | ~0x3F); + uvalue = (byte | ~0x3F); else - *value = (byte & 0x3F); + uvalue = (byte & 0x3F); if (byte & 0x80) { @@ -817,8 +819,9 @@ static INLINE BOOL update_read_delta(wStream* s, INT32* value) return FALSE; Stream_Read_UINT8(s, byte); - *value = (*value << 8) | byte; + uvalue = (uvalue << 8) | byte; } + *value = (INT32)uvalue; return TRUE; } @@ -2171,7 +2174,9 @@ static BOOL update_read_ellipse_cb_order(const char* orderName, wStream* s, return TRUE; return FALSE; } + /* Secondary Drawing Orders */ +WINPR_ATTR_MALLOC(free_cache_bitmap_order, 2) static CACHE_BITMAP_ORDER* update_read_cache_bitmap_order(rdpUpdate* update, wStream* s, BOOL compressed, UINT16 flags) { @@ -2290,6 +2295,7 @@ BOOL update_write_cache_bitmap_order(wStream* s, const CACHE_BITMAP_ORDER* cache return TRUE; } +WINPR_ATTR_MALLOC(free_cache_bitmap_v2_order, 2) static CACHE_BITMAP_V2_ORDER* update_read_cache_bitmap_v2_order(rdpUpdate* update, wStream* s, BOOL compressed, UINT16 flags) { @@ -2466,6 +2472,8 @@ BOOL update_write_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache cache_bitmap_v2->compressed = compressed; return TRUE; } + +WINPR_ATTR_MALLOC(free_cache_bitmap_v3_order, 2) static CACHE_BITMAP_V3_ORDER* update_read_cache_bitmap_v3_order(rdpUpdate* update, wStream* s, UINT16 flags) { @@ -2571,6 +2579,8 @@ BOOL update_write_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache Stream_Write(s, bitmapData->data, bitmapData->length); return TRUE; } + +WINPR_ATTR_MALLOC(free_cache_color_table_order, 2) static CACHE_COLOR_TABLE_ORDER* update_read_cache_color_table_order(rdpUpdate* update, wStream* s, UINT16 flags) { diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 42c4c21..fba9281 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -1532,6 +1532,7 @@ BOOL freerdp_peer_context_new_ex(freerdp_peer* client, const rdpSettings* settin if (!client) return FALSE; + WINPR_ASSERT(client->ContextSize >= sizeof(rdpContext)); if (!(context = (rdpContext*)calloc(1, client->ContextSize))) goto fail; diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c index 8538a90..5343a07 100644 --- a/libfreerdp/core/redirection.c +++ b/libfreerdp/core/redirection.c @@ -243,7 +243,7 @@ static BOOL rdp_redirection_read_base64_wchar(UINT32 flag, wStream* s, UINT32* p const WCHAR* wchar = (const WCHAR*)ptr; size_t utf8_len = 0; - char* utf8 = ConvertWCharNToUtf8Alloc(wchar, *pLength, &utf8_len); + char* utf8 = ConvertWCharNToUtf8Alloc(wchar, *pLength / sizeof(WCHAR), &utf8_len); if (!utf8) goto fail; diff --git a/libfreerdp/core/test/CMakeLists.txt b/libfreerdp/core/test/CMakeLists.txt index ebd8fef..9b2e654 100644 --- a/libfreerdp/core/test/CMakeLists.txt +++ b/libfreerdp/core/test/CMakeLists.txt @@ -10,7 +10,9 @@ set(${MODULE_PREFIX}_TESTS TestSettings.c) set(FUZZERS - TestFuzzCryptoCertificateDataSetPEM.c + TestFuzzCoreClient.c + TestFuzzCoreServer.c + TestFuzzCryptoCertificateDataSetPEM.c ) if(WITH_SAMPLE AND WITH_SERVER AND NOT WIN32) @@ -34,7 +36,7 @@ add_definitions(-DTESTING_SRC_DIRECTORY="${PROJECT_SOURCE_DIR}") target_link_libraries(${MODULE_NAME} freerdp winpr freerdp-client) include (AddFuzzerTest) -add_fuzzer_test("${FUZZERS}" "freerdp winpr") +add_fuzzer_test("${FUZZERS}" "freerdp-client freerdp winpr") set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") @@ -44,4 +46,3 @@ foreach(test ${${MODULE_PREFIX}_TESTS}) endforeach() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/Core/Test") - diff --git a/libfreerdp/core/test/TestFuzzCoreClient.c b/libfreerdp/core/test/TestFuzzCoreClient.c new file mode 100644 index 0000000..5c67497 --- /dev/null +++ b/libfreerdp/core/test/TestFuzzCoreClient.c @@ -0,0 +1,116 @@ +#include <freerdp/client.h> + +#include "../fastpath.h" +#include "../surface.h" +#include "../window.h" +#include "../info.h" +#include "../multitransport.h" + +static BOOL test_client(const uint8_t* Data, size_t Size) +{ + RDP_CLIENT_ENTRY_POINTS entry = { 0 }; + + entry.Version = RDP_CLIENT_INTERFACE_VERSION; + entry.Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1); + entry.ContextSize = sizeof(rdpContext); + + rdpContext* context = freerdp_client_context_new(&entry); + if (!context) + goto fail; + + rdpRdp* rdp = context->rdp; + WINPR_ASSERT(rdp); + + wStream sbuffer = { 0 }; + wStream* s = Stream_StaticConstInit(&sbuffer, Data, Size); + + { + rdpFastPath* fastpath = rdp->fastpath; + WINPR_ASSERT(fastpath); + + fastpath_recv_updates(fastpath, s); + fastpath_recv_inputs(fastpath, s); + + UINT16 length = 0; + fastpath_read_header_rdp(fastpath, s, &length); + fastpath_decrypt(fastpath, s, &length); + } + + { + UINT16 length = 0; + UINT16 flags = 0; + UINT16 channelId = 0; + UINT16 tpktLength = 0; + UINT16 remainingLength = 0; + UINT16 type = 0; + UINT16 securityFlags = 0; + UINT32 share_id = 0; + BYTE compressed_type = 0; + BYTE btype = 0; + UINT16 compressed_len = 0; + + rdp_recv_callback(rdp->transport, s, rdp); + rdp_read_security_header(rdp, s, &flags, &length); + rdp_read_header(rdp, s, &length, &channelId); + rdp_read_share_control_header(rdp, s, &tpktLength, &remainingLength, &type, &channelId); + rdp_read_share_data_header(rdp, s, &length, &btype, &share_id, &compressed_type, + &compressed_len); + rdp_recv_enhanced_security_redirection_packet(rdp, s); + rdp_recv_out_of_sequence_pdu(rdp, s, type, length); + rdp_recv_message_channel_pdu(rdp, s, securityFlags); + } + { + rdpUpdate* update = rdp->update; + UINT16 channelId = 0; + UINT16 length = 0; + UINT16 pduSource = 0; + UINT16 pduLength = 0; + update_recv_order(update, s); + update_recv_altsec_window_order(update, s); + update_recv_play_sound(update, s); + update_recv_pointer(update, s); + update_recv_surfcmds(update, s); + rdp_recv_get_active_header(rdp, s, &channelId, &length); + rdp_recv_demand_active(rdp, s, pduSource, length); + rdp_recv_confirm_active(rdp, s, pduLength); + } + { + rdpNla* nla = nla_new(rdp->context, rdp->transport); + nla_recv_pdu(nla, s); + nla_free(nla); + } + { + rdp_recv_heartbeat_packet(rdp, s); + rdp->state = CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE; + rdp_recv_client_info(rdp, s); + rdp_recv_save_session_info(rdp, s); + } + { + freerdp_is_valid_mcs_create_request(Data, Size); + freerdp_is_valid_mcs_create_response(Data, Size); + } + { + multitransport_recv_request(rdp->multitransport, s); + multitransport_recv_response(rdp->multitransport, s); + } + { + autodetect_recv_request_packet(rdp->autodetect, RDP_TRANSPORT_TCP, s); + autodetect_recv_response_packet(rdp->autodetect, RDP_TRANSPORT_TCP, s); + } + { + rdp_recv_deactivate_all(rdp, s); + rdp_recv_server_synchronize_pdu(rdp, s); + rdp_recv_client_synchronize_pdu(rdp, s); + + rdp_recv_data_pdu(rdp, s); + rdp_recv_font_map_pdu(rdp, s); + } +fail: + freerdp_client_context_free(context); +} + +int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) +{ + test_client(Data, Size); + return 0; +} diff --git a/libfreerdp/core/test/TestFuzzCoreServer.c b/libfreerdp/core/test/TestFuzzCoreServer.c new file mode 100644 index 0000000..cd469f4 --- /dev/null +++ b/libfreerdp/core/test/TestFuzzCoreServer.c @@ -0,0 +1,108 @@ +#include <freerdp/peer.h> + +#include "../fastpath.h" +#include "../surface.h" +#include "../window.h" +#include "../info.h" +#include "../multitransport.h" + +static BOOL test_server(const uint8_t* Data, size_t Size) +{ + freerdp_peer* client = calloc(1, sizeof(freerdp_peer)); + if (!client) + goto fail; + client->ContextSize = sizeof(rdpContext); + if (!freerdp_peer_context_new(client)) + goto fail; + + WINPR_ASSERT(client->context); + rdpRdp* rdp = client->context->rdp; + WINPR_ASSERT(rdp); + + wStream sbuffer = { 0 }; + wStream* s = Stream_StaticConstInit(&sbuffer, Data, Size); + + { + rdpFastPath* fastpath = rdp->fastpath; + WINPR_ASSERT(fastpath); + + fastpath_recv_updates(fastpath, s); + fastpath_recv_inputs(fastpath, s); + + UINT16 length = 0; + fastpath_read_header_rdp(fastpath, s, &length); + fastpath_decrypt(fastpath, s, &length); + } + + { + UINT16 length = 0; + UINT16 flags = 0; + UINT16 channelId = 0; + UINT16 tpktLength = 0; + UINT16 remainingLength = 0; + UINT16 type = 0; + UINT16 securityFlags = 0; + UINT32 share_id = 0; + BYTE compressed_type = 0; + BYTE btype = 0; + UINT16 compressed_len = 0; + rdp_read_security_header(rdp, s, &flags, &length); + rdp_read_header(rdp, s, &length, &channelId); + rdp_read_share_control_header(rdp, s, &tpktLength, &remainingLength, &type, &channelId); + rdp_read_share_data_header(rdp, s, &length, &btype, &share_id, &compressed_type, + &compressed_len); + rdp_recv_message_channel_pdu(rdp, s, securityFlags); + } + { + rdpUpdate* update = rdp->update; + UINT16 channelId = 0; + UINT16 length = 0; + UINT16 pduSource = 0; + UINT16 pduLength = 0; + update_recv_order(update, s); + update_recv_altsec_window_order(update, s); + update_recv_play_sound(update, s); + update_recv_pointer(update, s); + update_recv_surfcmds(update, s); + rdp_recv_get_active_header(rdp, s, &channelId, &length); + rdp_recv_demand_active(rdp, s, pduSource, length); + rdp_recv_confirm_active(rdp, s, pduLength); + } + { + rdpNla* nla = nla_new(rdp->context, rdp->transport); + nla_recv_pdu(nla, s); + nla_free(nla); + } + { + rdp_recv_heartbeat_packet(rdp, s); + rdp->state = CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE; + rdp_recv_client_info(rdp, s); + rdp_recv_save_session_info(rdp, s); + } + { + freerdp_is_valid_mcs_create_request(Data, Size); + freerdp_is_valid_mcs_create_response(Data, Size); + } + { + multitransport_recv_request(rdp->multitransport, s); + multitransport_recv_response(rdp->multitransport, s); + } + { + autodetect_recv_request_packet(rdp->autodetect, RDP_TRANSPORT_TCP, s); + autodetect_recv_response_packet(rdp->autodetect, RDP_TRANSPORT_TCP, s); + } + { + rdp_recv_deactivate_all(rdp, s); + rdp_recv_server_synchronize_pdu(rdp, s); + rdp_recv_client_synchronize_pdu(rdp, s); + } +fail: + freerdp_peer_context_free(client); + free(client); +} + +int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) +{ + test_server(Data, Size); + return 0; +} diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index cfc0abc..9e79863 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -2031,7 +2031,9 @@ static BOOL update_send_cache_brush(rdpContext* context, const CACHE_BRUSH_ORDER return FALSE; const size_t em = Stream_GetPosition(s); - WINPR_ASSERT(em > bm + 13); + if (em <= bm + 13) + return FALSE; + const size_t orderLength = (em - bm) - 13; WINPR_ASSERT(orderLength <= UINT16_MAX); Stream_SetPosition(s, bm); @@ -3299,6 +3301,9 @@ void update_free(rdpUpdate* update) MessageQueue_Free(up->queue); DeleteCriticalSection(&up->mux); + + if (up->us) + Stream_Free(up->us, TRUE); free(update); } } @@ -3328,7 +3333,9 @@ BOOL update_begin_paint(rdpUpdate* update) /* Reset the invalid regions, we start a new frame here. */ rdpGdi* gdi = update->context->gdi; - WINPR_ASSERT(gdi); + if (!gdi) + return FALSE; + if (gdi->hdc && gdi->primary && gdi->primary->hdc) { HGDI_WND hwnd = gdi->primary->hdc->hwnd; |