diff --git a/SOURCES/channels-audin-limit-FramesPerPacket.patch b/SOURCES/channels-audin-limit-FramesPerPacket.patch new file mode 100644 index 0000000..711959f --- /dev/null +++ b/SOURCES/channels-audin-limit-FramesPerPacket.patch @@ -0,0 +1,37 @@ +From 97e9d90528690f6973398c9d7e4f8da52145f669 Mon Sep 17 00:00:00 2001 +From: Armin Novak +Date: Sun, 12 Jul 2026 17:37:48 +0200 +Subject: [PATCH] [channels,audin] limit FramesPerPacket + +--- + channels/audin/client/audin_main.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c +index 332aef9da..186e356cd 100644 +--- a/channels/audin/client/audin_main.c ++++ b/channels/audin/client/audin_main.c +@@ -488,7 +488,6 @@ static UINT audin_process_open(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* cal + Stream_Read_UINT32(s, initialFormat); + WLog_Print(audin->log, WLOG_DEBUG, "FramesPerPacket=%" PRIu32 " initialFormat=%" PRIu32 "", + FramesPerPacket, initialFormat); +- audin->FramesPerPacket = FramesPerPacket; + + if (initialFormat >= callback->formats_count) + { +@@ -496,6 +496,15 @@ static UINT audin_process_open(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* cal + return ERROR_INVALID_DATA; + } + ++ /* The RDP protocol field allows UINT32_MAX, but most backend API use INT32 as input parameter ++ * or do some math with it, so ensure that the value does not exceed reasonable limits */ ++ if (FramesPerPacket >= INT32_MAX) ++ { ++ WLog_Print(audin->log, WLOG_ERROR, "invalid frames per packet %" PRIu32, FramesPerPacket); ++ return ERROR_INVALID_DATA; ++ } ++ ++ audin->FramesPerPacket = FramesPerPacket; + audin->format = &callback->formats[initialFormat]; + + if (!audin_open_device(audin, callback)) diff --git a/SOURCES/client-common-deactivate-cli-parsing-in-rdp-files.patch b/SOURCES/client-common-deactivate-cli-parsing-in-rdp-files.patch new file mode 100644 index 0000000..874b1a3 --- /dev/null +++ b/SOURCES/client-common-deactivate-cli-parsing-in-rdp-files.patch @@ -0,0 +1,65 @@ +From 20a3489c23763f94d31dcf8fd7ed880e07cbb2e8 Mon Sep 17 00:00:00 2001 +From: Armin Novak +Date: Thu, 2 Jul 2026 10:21:54 +0200 +Subject: [PATCH] [client,common] deactivate cli parsing in RDP files + +This feature was uncodumented and might have unintended side effects. +Deactivate it by default and (for the time being) keep an option to +enable it at compile time. +--- + client/common/CMakeLists.txt | 5 +++++ + client/common/file.c | 4 ++++ + 2 files changed, 9 insertions(+) + +diff --git a/client/common/CMakeLists.txt b/client/common/CMakeLists.txt +index b465a6311..7bc7cf083 100644 +--- a/client/common/CMakeLists.txt ++++ b/client/common/CMakeLists.txt +@@ -85,6 +85,11 @@ if (WITH_DEBUG_SYMBOLS AND MSVC AND BUILD_SHARED_LIBS) + install(FILES ${CMAKE_PDB_BINARY_DIR}/${OUTPUT_FILENAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols) + endif() + ++option(WITH_EMBEDDED_CLI_IN_RDP_FILES "[dangrous] allow embedded cli arguments in rdp files" OFF) ++if(WITH_EMBEDDED_CLI_IN_RDP_FILES) ++ add_compile_definitions(WITH_EMBEDDED_CLI_IN_RDP_FILES) ++endif() ++ + set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Common") + + if(BUILD_TESTING) +diff --git a/client/common/file.c b/client/common/file.c +index b56fe6f06..bff94bad0 100644 +--- a/client/common/file.c ++++ b/client/common/file.c +@@ -26,6 +26,7 @@ + + #include + ++ + #include + #include + +@@ -661,6 +662,7 @@ static BOOL trim_strings(rdpFile* file) + return FALSE; + if (!trim(&file->KdcProxyName)) + return FALSE; ++ + return TRUE; + } + +@@ -721,6 +723,7 @@ BOOL freerdp_client_parse_rdp_file_buffer_ex(rdpFile* file, const BYTE* buffer, + if (freerdp_client_parse_rdp_file_add_line(file, line, index) == -1) + goto fail; + ++#if defined(WITH_EMBEDDED_CLI_IN_RDP_FILES) + if (beg[0] == '/') + { + if (!freerdp_client_parse_rdp_file_option(file, line, index)) +@@ -728,6 +731,7 @@ BOOL freerdp_client_parse_rdp_file_buffer_ex(rdpFile* file, const BYTE* buffer, + + goto next_line; /* FreeRDP option */ + } ++#endif + + d1 = strchr(line, ':'); + diff --git a/SOURCES/core-message-fix-update_message_WindowIcon.patch b/SOURCES/core-message-fix-update_message_WindowIcon.patch new file mode 100644 index 0000000..f6481b1 --- /dev/null +++ b/SOURCES/core-message-fix-update_message_WindowIcon.patch @@ -0,0 +1,37 @@ +From 9397fbeed4b2862ae68f9556950af415163c9398 Mon Sep 17 00:00:00 2001 +From: Armin Novak +Date: Tue, 7 Jul 2026 12:58:11 +0200 +Subject: [PATCH] [core,message] fix update_message_WindowIcon + +--- + libfreerdp/core/message.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/libfreerdp/core/message.c b/libfreerdp/core/message.c +index 7af29e94d..1ab0d4e4e 100644 +--- a/libfreerdp/core/message.c ++++ b/libfreerdp/core/message.c +@@ -1147,18 +1147,21 @@ static BOOL update_message_WindowIcon(rdpContext* context, const WINDOW_ORDER_IN + if (!wParam) + return FALSE; + +- CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO)); ++ *wParam = *orderInfo; ++ + lParam = (WINDOW_ICON_ORDER*)calloc(1, sizeof(WINDOW_ICON_ORDER)); + + if (!lParam) + goto out_fail; + ++ *lParam = *windowIcon; + lParam->iconInfo = calloc(1, sizeof(ICON_INFO)); + + if (!lParam->iconInfo) + goto out_fail; + +- CopyMemory(lParam, windowIcon, sizeof(WINDOW_ICON_ORDER)); ++ *lParam->iconInfo = *windowIcon->iconInfo; ++ + WLog_VRB(TAG, "update_message_WindowIcon"); + + if (windowIcon->iconInfo->cbBitsColor > 0) diff --git a/SOURCES/core-redirection-check-redirection-values-for-validity.patch b/SOURCES/core-redirection-check-redirection-values-for-validity.patch new file mode 100644 index 0000000..5360500 --- /dev/null +++ b/SOURCES/core-redirection-check-redirection-values-for-validity.patch @@ -0,0 +1,163 @@ +From cdabc78fc50a5a1859faebc1e41a3dfbbd007341 Mon Sep 17 00:00:00 2001 +From: Armin Novak +Date: Thu, 9 Jul 2026 08:34:24 +0200 +Subject: [PATCH] [core,redirection] check redirection values for validity + +Add some basic validity checks for data provided by server. +--- + libfreerdp/core/redirection.c | 25 ++++++++++++++++++++----- + libfreerdp/core/utils.c | 33 +++++++++++++++++++++++++++++++++ + libfreerdp/core/utils.h | 2 ++ + 3 files changed, 55 insertions(+), 5 deletions(-) + +diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c +index 59c6dbcee..b4b222eb2 100644 +--- a/libfreerdp/core/redirection.c ++++ b/libfreerdp/core/redirection.c +@@ -406,6 +406,8 @@ static int rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) + { + if (!rdp_redirection_read_unicode_string(s, &(redirection->TargetNetAddress), 80)) + return -1; ++ if (!utils_is_valid_ip(redirection->TargetNetAddress)) ++ return -1; + } + + if (redirection->flags & LB_LOAD_BALANCE_INFO) +@@ -419,13 +421,17 @@ static int rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) + if (!rdp_redirection_read_data(LB_LOAD_BALANCE_INFO, s, &redirection->LoadBalanceInfoLength, + &redirection->LoadBalanceInfo)) + return -1; ++ if (!winpr_str_is_valid_urlN((const char*)redirection->LoadBalanceInfo, ++ redirection->LoadBalanceInfoLength)) ++ return -1; + } + + if (redirection->flags & LB_USERNAME) + { + if (!rdp_redirection_read_unicode_string(s, &(redirection->Username), 512)) + return -1; +- ++ if (winpr_str_has_newlines(redirection->Username)) ++ return -1; + WLog_DBG(TAG, "Username: %s", redirection->Username); + } + +@@ -433,7 +439,8 @@ static int rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) + { + if (!rdp_redirection_read_unicode_string(s, &(redirection->Domain), 52)) + return -1; +- ++ if (winpr_str_has_newlines(redirection->Domain)) ++ return -1; + WLog_DBG(TAG, "Domain: %s", redirection->Domain); + } + +@@ -484,7 +491,8 @@ static int rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) + { + if (!rdp_redirection_read_unicode_string(s, &(redirection->TargetFQDN), 512)) + return -1; +- ++ if (!winpr_str_is_valid_url(redirection->TargetFQDN)) ++ return -1; + WLog_DBG(TAG, "TargetFQDN: %s", redirection->TargetFQDN); + } + +@@ -492,7 +500,8 @@ static int rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) + { + if (!rdp_redirection_read_unicode_string(s, &(redirection->TargetNetBiosName), 32)) + return -1; +- ++ if (!winpr_str_is_valid_url(redirection->TargetNetBiosName)) ++ return -1; + WLog_DBG(TAG, "TargetNetBiosName: %s", redirection->TargetNetBiosName); + } + +@@ -501,6 +510,8 @@ static int rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) + if (!rdp_redirection_read_data(LB_CLIENT_TSV_URL, s, &redirection->TsvUrlLength, + &redirection->TsvUrl)) + return -1; ++ if (!winpr_str_is_valid_urlN((const char*)redirection->TsvUrl, redirection->TsvUrlLength)) ++ return -1; + } + + if (redirection->flags & LB_REDIRECTION_GUID) +@@ -541,7 +552,8 @@ static int rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) + { + if (!rdp_redirection_read_unicode_string(s, &(redirection->TargetNetAddresses[i]), 80)) + return -1; +- ++ if (!utils_is_valid_ip(redirection->TargetNetAddresses[i])) ++ return -1; + WLog_DBG(TAG, "TargetNetAddresses[%" PRIuz "]: %s", i, + redirection->TargetNetAddresses[i]); + } +@@ -569,7 +581,10 @@ int rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, wStream* s) + status = rdp_recv_server_redirection_pdu(rdp, s); + + if (status < 0) ++ { ++ WLog_ERR(TAG, "redirection packet invalid, aborting"); + return status; ++ } + + if (Stream_GetRemainingLength(s) >= 1) + { +diff --git a/libfreerdp/core/utils.c b/libfreerdp/core/utils.c +index 139c1a433..102819915 100644 +--- a/libfreerdp/core/utils.c ++++ b/libfreerdp/core/utils.c +@@ -22,6 +22,16 @@ + #include "config.h" + #endif + ++#include ++ ++#ifdef _WIN32 ++#include ++#else ++#include ++#include ++#include ++#endif ++ + #include + + #include +@@ -65,3 +75,26 @@ BOOL utils_str_is_empty(const char* str) + return TRUE; + return FALSE; + } ++ ++static BOOL isValidIPv4(const char* ipAddress) ++{ ++ struct sockaddr_in sa; ++ int result; ++ memset(&sa, 0, sizeof(sa)); ++ result = inet_pton(AF_INET, ipAddress, &(sa.sin_addr)); ++ return result != 0; ++} ++ ++static BOOL isValidIPv6(const char* ipAddress) ++{ ++ struct sockaddr_in6 sa; ++ int result; ++ memset(&sa, 0, sizeof(sa)); ++ result = inet_pton(AF_INET6, ipAddress, &(sa.sin6_addr)); ++ return result != 0; ++} ++ ++BOOL utils_is_valid_ip(const char* ipAddress) ++{ ++ return isValidIPv4(ipAddress) || isValidIPv6(ipAddress); ++} +diff --git a/libfreerdp/core/utils.h b/libfreerdp/core/utils.h +index 432951812..4b150c416 100644 +--- a/libfreerdp/core/utils.h ++++ b/libfreerdp/core/utils.h +@@ -30,4 +30,6 @@ BOOL utils_abort_connect(rdpContext* context); + BOOL utils_str_is_empty(const char* str); + BOOL utils_str_copy(const char* value, char** dst); + ++FREERDP_LOCAL BOOL utils_is_valid_ip(const char* ipAddress); ++ + #endif /* FREERDP_LIB_CORE_UTILS_H */ diff --git a/SOURCES/core-redirection-relax-checks.patch b/SOURCES/core-redirection-relax-checks.patch new file mode 100644 index 0000000..a003e4c --- /dev/null +++ b/SOURCES/core-redirection-relax-checks.patch @@ -0,0 +1,34 @@ +From b3cff65a1adbbdeda478f035218eeadc72ca0032 Mon Sep 17 00:00:00 2001 +From: Armin Novak +Date: Tue, 14 Jul 2026 12:30:27 +0200 +Subject: [PATCH] [core,redirection] relax checks + +* TsvUrl is opaque, do not assume any format +* LoadBalanceInfo is opaque, do not assume any format +--- + libfreerdp/core/redirection.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c +index b4b222eb2..773496603 100644 +--- a/libfreerdp/core/redirection.c ++++ b/libfreerdp/core/redirection.c +@@ -421,9 +421,6 @@ static int rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) + if (!rdp_redirection_read_data(LB_LOAD_BALANCE_INFO, s, &redirection->LoadBalanceInfoLength, + &redirection->LoadBalanceInfo)) + return -1; +- if (!winpr_str_is_valid_urlN((const char*)redirection->LoadBalanceInfo, +- redirection->LoadBalanceInfoLength)) +- return -1; + } + + if (redirection->flags & LB_USERNAME) +@@ -510,8 +507,6 @@ static int rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s) + if (!rdp_redirection_read_data(LB_CLIENT_TSV_URL, s, &redirection->TsvUrlLength, + &redirection->TsvUrl)) + return -1; +- if (!winpr_str_is_valid_urlN((const char*)redirection->TsvUrl, redirection->TsvUrlLength)) +- return -1; + } + + if (redirection->flags & LB_REDIRECTION_GUID) diff --git a/SOURCES/winpr-crt-add-functions-to-test-string.patch b/SOURCES/winpr-crt-add-functions-to-test-string.patch new file mode 100644 index 0000000..bb364ac --- /dev/null +++ b/SOURCES/winpr-crt-add-functions-to-test-string.patch @@ -0,0 +1,266 @@ +From a7a47bc0bdab723b674fb05f51e93ae007ed6412 Mon Sep 17 00:00:00 2001 +From: Armin Novak +Date: Thu, 9 Jul 2026 08:34:23 +0200 +Subject: [PATCH] [winpr,crt] add functions to test string + +* winpr_str_has_newlines to check for newlines in a string +* winpr_str_is_valid_url and winpr_str_is_valid_urlN to check if a + string is a valid url +--- + winpr/include/winpr/string.h | 5 ++ + winpr/libwinpr/crt/CMakeLists.txt | 8 +++ + winpr/libwinpr/crt/string.c | 96 ++++++++++++++++++++++++++++ + winpr/libwinpr/crt/test/TestString.c | 82 ++++++++++++++++++++++++ + 4 files changed, 191 insertions(+) + +diff --git a/winpr/include/winpr/string.h b/winpr/include/winpr/string.h +index bb98dffdc..7de9f934f 100644 +--- a/winpr/include/winpr/string.h ++++ b/winpr/include/winpr/string.h +@@ -31,6 +31,11 @@ extern "C" + { + #endif + ++ WINPR_API BOOL winpr_str_is_valid_url(const char* str); ++ WINPR_API BOOL winpr_str_is_valid_urlN(const char* str, size_t len); ++ WINPR_API BOOL winpr_str_has_newlines(const char* str); ++ ++ + WINPR_API BOOL winpr_str_append(const char* what, char* buffer, size_t size, + const char* separator); + +diff --git a/winpr/libwinpr/crt/CMakeLists.txt b/winpr/libwinpr/crt/CMakeLists.txt +index 5ee4bbd1e..538e74dcf 100644 +--- a/winpr/libwinpr/crt/CMakeLists.txt ++++ b/winpr/libwinpr/crt/CMakeLists.txt +@@ -22,6 +22,14 @@ set (CRT_FILES alignment.c + unicode.c + string.c) + ++include(CheckSymbolExists) ++check_symbol_exists(regcomp regex.h WINPR_HAVE_REGCOMP) ++check_symbol_exists(regexec regex.h WINPR_HAVE_REGEXEC) ++check_symbol_exists(regfree regex.h WINPR_HAVE_REGFREE) ++if(WINPR_HAVE_REGCOMP AND WINPR_HAVE_REGEXEC AND WINPR_HAVE_REGFREE) ++ winpr_definition_add(-DWINPR_HAVE_REGCOMP) ++endif() ++ + if (NOT WITH_ICU) + set (CRT_FILES ${CRT_FILES} + utf.c +diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c +index 6596b42f5..465b8d133 100644 +--- a/winpr/libwinpr/crt/string.c ++++ b/winpr/libwinpr/crt/string.c +@@ -29,11 +29,71 @@ + #include + #include + ++#if defined(WINPR_HAVE_REGCOMP) ++#include ++#endif ++ + /* String Manipulation (CRT): http://msdn.microsoft.com/en-us/library/f0151s4x.aspx */ + + #include "../log.h" + #define TAG WINPR_TAG("crt") + ++BOOL winpr_str_is_valid_urlN(const char* str, size_t len) ++{ ++ if (!str || (len == 0)) ++ return FALSE; ++ ++ char* url = strndup(str, len); ++ if (!url) ++ return FALSE; ++ ++ const BOOL rc = winpr_str_is_valid_url(url); ++ free(url); ++ return rc; ++} ++ ++#if defined(_WIN32) ++#include ++ ++BOOL winpr_str_is_valid_url(const char* str) ++{ ++ if (!str) ++ return FALSE; ++ return PathIsURLA(str); ++} ++ ++#elif defined(WINPR_HAVE_REGCOMP) ++BOOL winpr_str_is_valid_url(const char* str) ++{ ++ regex_t regex; ++ const char pattern[] = "^([a-z]+://)?([a-zA-Z0-9.-]+)(:[0-9]+)?(/[a-zA-Z0-9./?=&%-]*)?$"; ++ int ret; ++ ++ if (!str) ++ return FALSE; ++ memset(®ex, 0, sizeof(regex)); ++ ++ ret = regcomp(®ex, pattern, REG_EXTENDED); ++ if (ret) ++ { ++ printf("Could not compile regex\n"); ++ return FALSE; ++ } ++ ++ ret = regexec(®ex, str, 0, NULL, 0); ++ regfree(®ex); ++ return ret == 0; ++} ++ ++#else ++BOOL winpr_str_is_valid_url(const char* str) ++{ ++ WINPR_UNUSED(str); ++ WLog_WARN(TAG, "URL validation not supported by your build, not performing check."); ++ return TRUE; ++} ++#endif ++ + BOOL winpr_str_append(const char* what, char* buffer, size_t size, const char* separator) + { + const size_t used = strnlen(buffer, size); +@@ -636,3 +696,39 @@ INT64 GetLine(char** lineptr, size_t* size, FILE* stream) + return -1; + #endif + } ++ ++BOOL winpr_str_has_newlines(const char* str) ++{ ++ if (!str) ++ return FALSE; ++ do ++ { ++ char c = *str++; ++ switch (c) ++ { ++ case '\r': ++ case '\n': ++ case 0x0b: /* VT vertical tab */ ++ case 0x0c: /* FF form feed */ ++ case (char)0x85: /* NEL next line */ ++ return TRUE; ++ case 0x20: ++ { ++ switch (*str) ++ { ++ case 0x28: /* LS line separator */ ++ case 0x29: /* PS paragraph separator */ ++ return TRUE; ++ default: ++ break; ++ } ++ } ++ break; ++ ++ case '\0': ++ return FALSE; ++ default: ++ break; ++ } ++ } while (1); ++} +diff --git a/winpr/libwinpr/crt/test/TestString.c b/winpr/libwinpr/crt/test/TestString.c +index df154fe1c..bca470bdd 100644 +--- a/winpr/libwinpr/crt/test/TestString.c ++++ b/winpr/libwinpr/crt/test/TestString.c +@@ -27,6 +27,79 @@ static WCHAR testDelimiter[] = { '\r', '\n', '\0' }; + + #define testDelimiter_Length ((sizeof(testDelimiter) / sizeof(WCHAR)) - 1) + ++static BOOL test_valid_url(void) ++{ ++ struct test_t ++ { ++ char* string; ++ size_t len; ++ BOOL isUrl; ++ }; ++ ++ static const struct test_t tests[] = { { "foo.bar.blabla", 15, TRUE }, ++ { "somehostname", 12, TRUE }, ++ { "somehostname:1234", 17, TRUE }, ++ { "tsv://somehostname", 18, TRUE }, ++ { "tsv://somehostname/path/foo/gaga", 32, TRUE }, ++ { "tsv://somehostname:1234", 23, TRUE }, ++ { "tsv://somehostname:1234/path/foo", 33, TRUE }, ++ { "lala\rgaga\n", 12, FALSE }, ++ { "192.168.0.1", 11, TRUE }, ++ //{ "192.168.0.1:1234", 16, FALSE }, ++ //{ "192.168.0.1:1234/foo/", 21, FALSE }, ++ { "192.168.0.1/bar/foo/", 20, TRUE }, ++ { "[::1]", 5, FALSE }, ++ { "[::1]:1234", 8, FALSE }, ++ { "[2001:db8:3333:4444:5555:6666:7777:8888]", 40, ++ FALSE }, ++ { "[2001:db8::1]", 13, FALSE } }; ++ BOOL rc = TRUE; ++ for (size_t x = 0; x < ARRAYSIZE(tests); x++) ++ { ++ const struct test_t* cur = &tests[x]; ++ ++ const BOOL rc1 = winpr_str_is_valid_url(cur->string); ++ const BOOL rc2 = winpr_str_is_valid_urlN(cur->string, cur->len); ++ ++#if defined(WINPR_HAVE_REGCOMP) || defined(WITH_URIPARSER) ++ if (rc1 != rc2) ++ rc = FALSE; ++ if (rc1 != cur->isUrl) ++ rc = FALSE; ++#else ++ fprintf(stderr, "[%s] TODO: !defined(WINPR_HAVE_REGCOMP) && !defined(WITH_URIPARSER)\n", ++ __func__); ++#endif ++ } ++ ++ return rc; ++} ++ ++static BOOL test_newline(void) ++{ ++ struct test_t ++ { ++ char* string; ++ size_t len; ++ BOOL hasNewlines; ++ }; ++ ++ const struct test_t tests[] = { { "foo.bar.blabla", 15, FALSE }, ++ { "somehostname", 12, FALSE }, ++ { "lala\rgaga\n", 13, TRUE } }; ++ ++ for (size_t x = 0; x < ARRAYSIZE(tests); x++) ++ { ++ const struct test_t* cur = &tests[x]; ++ ++ const BOOL rc1 = winpr_str_has_newlines(cur->string); ++ if (rc1 != cur->hasNewlines) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ + int TestString(int argc, char* argv[]) + { + WCHAR* p; +@@ -34,6 +107,15 @@ int TestString(int argc, char* argv[]) + size_t length; + WCHAR* context; + ++ WINPR_UNUSED(argc); ++ WINPR_UNUSED(argv); ++ ++ if (!test_valid_url()) ++ return -1; ++ ++ if (!test_newline()) ++ return -1; ++ + #ifdef __BIG_ENDIAN__ + /* Be sure that we always use LE encoded string */ + ByteSwapUnicode(testStringW, testStringW_Length); diff --git a/SPECS/freerdp.spec b/SPECS/freerdp.spec index f5b8a2c..f230010 100644 --- a/SPECS/freerdp.spec +++ b/SPECS/freerdp.spec @@ -27,7 +27,7 @@ Name: freerdp Version: 2.11.7 -Release: 10%{?dist} +Release: 11%{?dist} Epoch: 2 Summary: Free implementation of the Remote Desktop Protocol (RDP) License: ASL 2.0 @@ -195,6 +195,26 @@ Patch45: client-x11-fix-deadlock-on-output-expose.patch # https://github.com/FreeRDP/FreeRDP/commit/4a065a941ae134a0433d1497c03b3c3eb91b9f85 Patch46: codec-planar-fix-bounds-checks.patch +# CVE-2026-64624 +# https://github.com/FreeRDP/FreeRDP/commit/22c5deea52404f51a13276b3abda44e1e60704cf +Patch47: client-common-deactivate-cli-parsing-in-rdp-files.patch + +# CVE-2026-67289 +# https://github.com/FreeRDP/FreeRDP/commit/f163b2d2080d922cb725800781f43f16bc2882c0 +# https://github.com/FreeRDP/FreeRDP/commit/ab5905cbada0d34cf85ffd32881cacaf8275744f +# https://github.com/FreeRDP/FreeRDP/commit/1db16b4b121a1221c0454f7d223096cac87bf244 +Patch48: winpr-crt-add-functions-to-test-string.patch +Patch49: core-redirection-check-redirection-values-for-validity.patch +Patch50: core-redirection-relax-checks.patch + +# CVE-2026-68580 +# https://github.com/FreeRDP/FreeRDP/commit/3bf07d4470bbe42faf4ef8197c8fe1b6b759b00f +Patch51: channels-audin-limit-FramesPerPacket.patch + +# CVE-2026-67299 +# https://github.com/FreeRDP/FreeRDP/commit/172edbddd24f33033b9eafae6ea1fff0641a24f4 +Patch52: core-message-fix-update_message_WindowIcon.patch + BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: alsa-lib-devel @@ -452,6 +472,11 @@ find %{buildroot} -name "*.a" -delete %{_libdir}/pkgconfig/winpr-tools2.pc %changelog +* Tue Aug 04 2026 RHEL Packaging Agent - 2:2.11.7-11 +- Backport several CVE fixes (CVE-2026-64624, CVE-2026-67289, CVE-2026-67299, + CVE-2026-68580) + Resolves: RHEL-213173, RHEL-222796, RHEL-222972, RHEL-223606 + * Wed Jun 24 2026 RHEL Packaging Agent - 2:2.11.7-10 - Fix incorrect bounds checks in planar codec (CVE-2026-45700) Resolves: RHEL-186983