summaryrefslogtreecommitdiffstats
path: root/libfreerdp/core
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:25:36 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:25:36 +0000
commit8050c230ded858d59518fce751e28713dd4266f9 (patch)
tree3b2835ad0af9b436b7ae77963fc10735adc13d25 /libfreerdp/core
parentAdding upstream version 3.5.0+dfsg1. (diff)
downloadfreerdp3-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.c4
-rw-r--r--libfreerdp/core/gcc.c5
-rw-r--r--libfreerdp/core/info.c4
-rw-r--r--libfreerdp/core/orders.c16
-rw-r--r--libfreerdp/core/peer.c1
-rw-r--r--libfreerdp/core/redirection.c2
-rw-r--r--libfreerdp/core/test/CMakeLists.txt7
-rw-r--r--libfreerdp/core/test/TestFuzzCoreClient.c116
-rw-r--r--libfreerdp/core/test/TestFuzzCoreServer.c108
-rw-r--r--libfreerdp/core/update.c11
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;