From 1a739f9beac7cc7d73d65fa20adffc5ea4c931a7 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Wed, 25 Feb 2026 07:23:25 +0000 Subject: [PATCH] import OL freerdp-3.10.3-5.el10_1.2 --- channels-rdpear-add-checks-for-itemSize.patch | 69 ++++++ ...pecam-ensure-all-streams-are-stopped.patch | 27 +++ ...c-check-interface-indices-before-use.patch | 197 ++++++++++++++++++ crypto-base64-ensure-char-is-singend.patch | 29 +++ freerdp.spec | 26 ++- ...smartcard-add-length-validity-checks.patch | 81 +++++++ 6 files changed, 428 insertions(+), 1 deletion(-) create mode 100644 channels-rdpear-add-checks-for-itemSize.patch create mode 100644 channels-rdpecam-ensure-all-streams-are-stopped.patch create mode 100644 channels-urbdrc-check-interface-indices-before-use.patch create mode 100644 crypto-base64-ensure-char-is-singend.patch create mode 100644 utils-smartcard-add-length-validity-checks.patch diff --git a/channels-rdpear-add-checks-for-itemSize.patch b/channels-rdpear-add-checks-for-itemSize.patch new file mode 100644 index 0000000..1d176c0 --- /dev/null +++ b/channels-rdpear-add-checks-for-itemSize.patch @@ -0,0 +1,69 @@ +From 19f48dc7d615984a24a9be89f50ef9eb8f9bdb6a Mon Sep 17 00:00:00 2001 +From: akallabeth +Date: Mon, 12 Jan 2026 15:02:53 +0100 +Subject: [PATCH] [channels,rdpear] add checks for itemSize + +when a ndr read function is called with invalid arguments abort early. +--- + channels/rdpear/common/ndr.c | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +diff --git a/channels/rdpear/common/ndr.c b/channels/rdpear/common/ndr.c +index d0bd6d959..ddb15a340 100644 +--- a/channels/rdpear/common/ndr.c ++++ b/channels/rdpear/common/ndr.c +@@ -518,6 +518,9 @@ BOOL ndr_read_uconformant_varying_array(NdrContext* context, wStream* s, + WINPR_ASSERT(itemType); + WINPR_ASSERT(ptarget); + ++ if (itemType->itemSize == 0) ++ return FALSE; ++ + UINT32 maxCount = 0; + UINT32 offset = 0; + UINT32 length = 0; +@@ -526,10 +529,10 @@ BOOL ndr_read_uconformant_varying_array(NdrContext* context, wStream* s, + !ndr_read_uint32(context, s, &length)) + return FALSE; + +- if ((length * itemType->itemSize) < hints->length) ++ if ((1ull * length * itemType->itemSize) > hints->length) + return FALSE; + +- if ((maxCount * itemType->itemSize) < hints->maxLength) ++ if ((1ull * maxCount * itemType->itemSize) > hints->maxLength) + return FALSE; + + BYTE* target = (BYTE*)ptarget; +@@ -552,6 +555,9 @@ BOOL ndr_write_uconformant_varying_array(NdrContext* context, wStream* s, + WINPR_ASSERT(itemType); + WINPR_ASSERT(psrc); + ++ if (itemType->itemSize == 0) ++ return FALSE; ++ + if (!ndr_write_uint32(context, s, hints->maxLength) || !ndr_write_uint32(context, s, 0) || + !ndr_write_uint32(context, s, hints->length)) + return FALSE; +@@ -581,8 +587,16 @@ BOOL ndr_read_uconformant_array(NdrContext* context, wStream* s, const NdrArrayH + if (!ndr_read_uint32(context, s, &count)) + return FALSE; + +- if ((count * itemType->itemSize < hints->count)) +- return FALSE; ++ if (itemType->arity == NDR_ARITY_SIMPLE) ++ { ++ if (count > hints->count) ++ return FALSE; ++ } ++ else ++ { ++ if ((1ull * count * itemType->itemSize) > hints->count) ++ return FALSE; ++ } + + BYTE* target = (BYTE*)vtarget; + for (UINT32 i = 0; i < count; i++, target += itemType->itemSize) +-- +2.52.0 + diff --git a/channels-rdpecam-ensure-all-streams-are-stopped.patch b/channels-rdpecam-ensure-all-streams-are-stopped.patch new file mode 100644 index 0000000..cf6cdbb --- /dev/null +++ b/channels-rdpecam-ensure-all-streams-are-stopped.patch @@ -0,0 +1,27 @@ +From f3ab1a16139036179d9852745fdade18fec11600 Mon Sep 17 00:00:00 2001 +From: akallabeth +Date: Mon, 26 Jan 2026 10:54:33 +0100 +Subject: [PATCH] [channels,rdpecam] ensure all streams are stopped + +When closing the channel ensure there are no more streams running. +--- + channels/rdpecam/client/camera_device_main.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/channels/rdpecam/client/camera_device_main.c b/channels/rdpecam/client/camera_device_main.c +index b76a37ca8..9ba3c65c5 100644 +--- a/channels/rdpecam/client/camera_device_main.c ++++ b/channels/rdpecam/client/camera_device_main.c +@@ -789,6 +789,9 @@ static UINT ecam_dev_on_close(IWTSVirtualChannelCallback* pChannelCallback) + + WLog_DBG(TAG, "entered"); + ++ for (size_t i = 0; i < ECAM_DEVICE_MAX_STREAMS; i++) ++ ecam_dev_stop_stream(dev, i); ++ + /* make sure this channel is not used for sample responses */ + for (size_t i = 0; i < ECAM_DEVICE_MAX_STREAMS; i++) + if (dev->streams[i].hSampleReqChannel == hchannel) +-- +2.52.0 + diff --git a/channels-urbdrc-check-interface-indices-before-use.patch b/channels-urbdrc-check-interface-indices-before-use.patch new file mode 100644 index 0000000..022ed0d --- /dev/null +++ b/channels-urbdrc-check-interface-indices-before-use.patch @@ -0,0 +1,197 @@ +From 7b7e6de8fe427a2f01d331056774aec69710590b Mon Sep 17 00:00:00 2001 +From: akallabeth +Date: Sat, 10 Jan 2026 08:43:40 +0100 +Subject: [PATCH] [channels,urbdrc] check interface indices before use + +--- + channels/urbdrc/client/data_transfer.c | 6 +- + .../urbdrc/client/libusb/libusb_udevice.c | 78 ++++++++++++------- + channels/urbdrc/common/msusb.c | 6 +- + 3 files changed, 54 insertions(+), 36 deletions(-) + +diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c +index e2270e565..762fe0d31 100644 +--- a/channels/urbdrc/client/data_transfer.c ++++ b/channels/urbdrc/client/data_transfer.c +@@ -454,14 +454,12 @@ static void func_select_all_interface_for_msconfig(IUDEVICE* pdev, + MSUSB_CONFIG_DESCRIPTOR* MsConfig) + { + MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfig->MsInterfaces; +- BYTE InterfaceNumber = 0; +- BYTE AlternateSetting = 0; + UINT32 NumInterfaces = MsConfig->NumInterfaces; + + for (UINT32 inum = 0; inum < NumInterfaces; inum++) + { +- InterfaceNumber = MsInterfaces[inum]->InterfaceNumber; +- AlternateSetting = MsInterfaces[inum]->AlternateSetting; ++ const BYTE InterfaceNumber = MsInterfaces[inum]->InterfaceNumber; ++ const BYTE AlternateSetting = MsInterfaces[inum]->AlternateSetting; + pdev->select_interface(pdev, InterfaceNumber, AlternateSetting); + } + } +diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c +index afc7f11c6..aa5639f09 100644 +--- a/channels/urbdrc/client/libusb/libusb_udevice.c ++++ b/channels/urbdrc/client/libusb/libusb_udevice.c +@@ -582,25 +582,13 @@ static MSUSB_CONFIG_DESCRIPTOR* + libusb_udev_complete_msconfig_setup(IUDEVICE* idev, MSUSB_CONFIG_DESCRIPTOR* MsConfig) + { + UDEVICE* pdev = (UDEVICE*)idev; +- MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = NULL; +- MSUSB_INTERFACE_DESCRIPTOR* MsInterface = NULL; +- MSUSB_PIPE_DESCRIPTOR** MsPipes = NULL; +- MSUSB_PIPE_DESCRIPTOR* MsPipe = NULL; +- MSUSB_PIPE_DESCRIPTOR** t_MsPipes = NULL; +- MSUSB_PIPE_DESCRIPTOR* t_MsPipe = NULL; +- LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig = NULL; +- const LIBUSB_INTERFACE* LibusbInterface = NULL; +- const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting = NULL; +- const LIBUSB_ENDPOINT_DESCEIPTOR* LibusbEndpoint = NULL; +- BYTE LibusbNumEndpoint = 0; +- URBDRC_PLUGIN* urbdrc = NULL; + UINT32 MsOutSize = 0; + + if (!pdev || !pdev->LibusbConfig || !pdev->urbdrc || !MsConfig) + return NULL; + +- urbdrc = pdev->urbdrc; +- LibusbConfig = pdev->LibusbConfig; ++ URBDRC_PLUGIN* urbdrc = pdev->urbdrc; ++ LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig = pdev->LibusbConfig; + + if (LibusbConfig->bNumInterfaces != MsConfig->NumInterfaces) + { +@@ -608,28 +596,57 @@ libusb_udev_complete_msconfig_setup(IUDEVICE* idev, MSUSB_CONFIG_DESCRIPTOR* MsC + "Select Configuration: Libusb NumberInterfaces(%" PRIu8 ") is different " + "with MsConfig NumberInterfaces(%" PRIu32 ")", + LibusbConfig->bNumInterfaces, MsConfig->NumInterfaces); ++ return NULL; + } + + /* replace MsPipes for libusb */ +- MsInterfaces = MsConfig->MsInterfaces; ++ MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfig->MsInterfaces; + + for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++) + { +- MsInterface = MsInterfaces[inum]; ++ MSUSB_INTERFACE_DESCRIPTOR* MsInterface = MsInterfaces[inum]; ++ if (MsInterface->InterfaceNumber >= MsConfig->NumInterfaces) ++ { ++ WLog_Print(urbdrc->log, WLOG_ERROR, ++ "MSUSB_CONFIG_DESCRIPTOR::NumInterfaces (%" PRIu32 ++ " <= MSUSB_INTERFACE_DESCRIPTOR::InterfaceNumber( %" PRIu8 ")", ++ MsConfig->NumInterfaces, MsInterface->InterfaceNumber); ++ return NULL; ++ } ++ ++ const LIBUSB_INTERFACE* LibusbInterface = ++ &LibusbConfig->interface[MsInterface->InterfaceNumber]; ++ if (MsInterface->AlternateSetting >= LibusbInterface->num_altsetting) ++ { ++ WLog_Print(urbdrc->log, WLOG_ERROR, ++ "LIBUSB_INTERFACE::num_altsetting (%" PRId32 ++ " <= MSUSB_INTERFACE_DESCRIPTOR::AlternateSetting( %" PRIu8 ")", ++ LibusbInterface->num_altsetting, MsInterface->AlternateSetting); ++ return NULL; ++ } ++ } ++ ++ for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++) ++ { ++ MSUSB_INTERFACE_DESCRIPTOR* MsInterface = MsInterfaces[inum]; ++ + /* get libusb's number of endpoints */ +- LibusbInterface = &LibusbConfig->interface[MsInterface->InterfaceNumber]; +- LibusbAltsetting = &LibusbInterface->altsetting[MsInterface->AlternateSetting]; +- LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints; +- t_MsPipes = ++ const LIBUSB_INTERFACE* LibusbInterface = ++ &LibusbConfig->interface[MsInterface->InterfaceNumber]; ++ const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting = ++ &LibusbInterface->altsetting[MsInterface->AlternateSetting]; ++ const BYTE LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints; ++ MSUSB_PIPE_DESCRIPTOR** t_MsPipes = + (MSUSB_PIPE_DESCRIPTOR**)calloc(LibusbNumEndpoint, sizeof(MSUSB_PIPE_DESCRIPTOR*)); + + for (UINT32 pnum = 0; pnum < LibusbNumEndpoint; pnum++) + { +- t_MsPipe = (MSUSB_PIPE_DESCRIPTOR*)calloc(1, sizeof(MSUSB_PIPE_DESCRIPTOR)); ++ MSUSB_PIPE_DESCRIPTOR* t_MsPipe = ++ (MSUSB_PIPE_DESCRIPTOR*)calloc(1, sizeof(MSUSB_PIPE_DESCRIPTOR)); + + if (pnum < MsInterface->NumberOfPipes && MsInterface->MsPipes) + { +- MsPipe = MsInterface->MsPipes[pnum]; ++ MSUSB_PIPE_DESCRIPTOR* MsPipe = MsInterface->MsPipes[pnum]; + t_MsPipe->MaximumPacketSize = MsPipe->MaximumPacketSize; + t_MsPipe->MaximumTransferSize = MsPipe->MaximumTransferSize; + t_MsPipe->PipeFlags = MsPipe->PipeFlags; +@@ -668,10 +685,12 @@ libusb_udev_complete_msconfig_setup(IUDEVICE* idev, MSUSB_CONFIG_DESCRIPTOR* MsC + for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++) + { + MsOutSize += 16; +- MsInterface = MsInterfaces[inum]; ++ MSUSB_INTERFACE_DESCRIPTOR* MsInterface = MsInterfaces[inum]; + /* get libusb's interface */ +- LibusbInterface = &LibusbConfig->interface[MsInterface->InterfaceNumber]; +- LibusbAltsetting = &LibusbInterface->altsetting[MsInterface->AlternateSetting]; ++ const LIBUSB_INTERFACE* LibusbInterface = ++ &LibusbConfig->interface[MsInterface->InterfaceNumber]; ++ const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting = ++ &LibusbInterface->altsetting[MsInterface->AlternateSetting]; + /* InterfaceHandle: 4 bytes + * --------------------------------------------------------------- + * ||<<< 1 byte >>>|<<< 1 byte >>>|<<< 1 byte >>>|<<< 1 byte >>>|| +@@ -688,15 +707,16 @@ libusb_udev_complete_msconfig_setup(IUDEVICE* idev, MSUSB_CONFIG_DESCRIPTOR* MsC + MsInterface->bInterfaceSubClass = LibusbAltsetting->bInterfaceSubClass; + MsInterface->bInterfaceProtocol = LibusbAltsetting->bInterfaceProtocol; + MsInterface->InitCompleted = 1; +- MsPipes = MsInterface->MsPipes; +- LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints; ++ MSUSB_PIPE_DESCRIPTOR** MsPipes = MsInterface->MsPipes; ++ const BYTE LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints; + + for (UINT32 pnum = 0; pnum < LibusbNumEndpoint; pnum++) + { + MsOutSize += 20; +- MsPipe = MsPipes[pnum]; ++ ++ MSUSB_PIPE_DESCRIPTOR* MsPipe = MsPipes[pnum]; + /* get libusb's endpoint */ +- LibusbEndpoint = &LibusbAltsetting->endpoint[pnum]; ++ const LIBUSB_ENDPOINT_DESCEIPTOR* LibusbEndpoint = &LibusbAltsetting->endpoint[pnum]; + /* PipeHandle: 4 bytes + * --------------------------------------------------------------- + * ||<<< 1 byte >>>|<<< 1 byte >>>|<<<<<<<<<< 2 byte >>>>>>>>>>>|| +diff --git a/channels/urbdrc/common/msusb.c b/channels/urbdrc/common/msusb.c +index 8d6809741..1b6e29aeb 100644 +--- a/channels/urbdrc/common/msusb.c ++++ b/channels/urbdrc/common/msusb.c +@@ -134,6 +134,8 @@ BOOL msusb_msinterface_replace(MSUSB_CONFIG_DESCRIPTOR* MsConfig, BYTE Interface + { + if (!MsConfig || !MsConfig->MsInterfaces) + return FALSE; ++ if (MsConfig->NumInterfaces <= InterfaceNumber) ++ return FALSE; + + msusb_msinterface_free(MsConfig->MsInterfaces[InterfaceNumber]); + MsConfig->MsInterfaces[InterfaceNumber] = NewMsInterface; +@@ -142,12 +144,10 @@ BOOL msusb_msinterface_replace(MSUSB_CONFIG_DESCRIPTOR* MsConfig, BYTE Interface + + MSUSB_INTERFACE_DESCRIPTOR* msusb_msinterface_read(wStream* s) + { +- MSUSB_INTERFACE_DESCRIPTOR* MsInterface = NULL; +- + if (!Stream_CheckAndLogRequiredCapacity(TAG, (s), 12)) + return NULL; + +- MsInterface = msusb_msinterface_new(); ++ MSUSB_INTERFACE_DESCRIPTOR* MsInterface = msusb_msinterface_new(); + + if (!MsInterface) + return NULL; +-- +2.52.0 + diff --git a/crypto-base64-ensure-char-is-singend.patch b/crypto-base64-ensure-char-is-singend.patch new file mode 100644 index 0000000..4f12e71 --- /dev/null +++ b/crypto-base64-ensure-char-is-singend.patch @@ -0,0 +1,29 @@ +From 525e717db19b57cc498bb2e3f1d9d65383f16d3f Mon Sep 17 00:00:00 2001 +From: Ondrej Holy +Date: Tue, 17 Feb 2026 14:54:30 +0100 +Subject: [PATCH] [crypto,base64] ensure char is singend + +Backport of commit 62a9e787edb2cfce9858fa4ceda5461680efc590. + +Co-Authored-By: Cursor +--- + libfreerdp/crypto/base64.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libfreerdp/crypto/base64.c b/libfreerdp/crypto/base64.c +index 315da9203..8d49d352e 100644 +--- a/libfreerdp/crypto/base64.c ++++ b/libfreerdp/crypto/base64.c +@@ -400,7 +400,8 @@ static INLINE char* base64_encode(const BYTE* WINPR_RESTRICT alphabet, + + static INLINE int base64_decode_char(const signed char* WINPR_RESTRICT alphabet, char c) + { +- if (c <= '\0') ++ /* ensure char is signed for this check */ ++ if ((int)c <= '\0') + return -1; + + return alphabet[(size_t)c]; +-- +2.52.0 + diff --git a/freerdp.spec b/freerdp.spec index 92e07f6..0d34367 100644 --- a/freerdp.spec +++ b/freerdp.spec @@ -30,7 +30,7 @@ Name: freerdp Epoch: 2 Version: 3.10.3 -Release: 5%{?dist}.1 +Release: 5%{?dist}.2 Summary: Free implementation of the Remote Desktop Protocol (RDP) # The effective license is Apache-2.0 but: @@ -77,6 +77,26 @@ Patch: client-x11-fix-double-free-in-case-of-invalid-pointe.patch # https://github.com/FreeRDP/FreeRDP/commit/52106a26726a2aba77aa6d86014d2eb3507f0783 Patch: cache-offscreen-invalidate-bitmap-before-free.patch +# CVE-2026-22853 +# https://github.com/FreeRDP/FreeRDP/commit/19f48dc7d615984a24a9be89f50ef9eb8f9bdb6a +Patch: channels-rdpear-add-checks-for-itemSize.patch + +# CVE-2026-22855 +# https://github.com/FreeRDP/FreeRDP/commit/57c5647d98c2a026de8b681159cb188ca0439ef8 +Patch: utils-smartcard-add-length-validity-checks.patch + +# CVE-2026-22858 +# https://github.com/FreeRDP/FreeRDP/commit/62a9e787edb2cfce9858fa4ceda5461680efc590 +Patch: crypto-base64-ensure-char-is-singend.patch + +# CVE-2026-22859 +# https://github.com/FreeRDP/FreeRDP/commit/7b7e6de8fe427a2f01d331056774aec69710590b +Patch: channels-urbdrc-check-interface-indices-before-use.patch + +# CVE-2026-24678 +# https://github.com/FreeRDP/FreeRDP/commit/f3ab1a16139036179d9852745fdade18fec11600 +Patch: channels-rdpecam-ensure-all-streams-are-stopped.patch + BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: alsa-lib-devel @@ -399,6 +419,10 @@ find %{buildroot} -name "*.a" -delete %{_libdir}/pkgconfig/winpr-tools3.pc %changelog +* Tue Feb 17 2026 Ondrej Holy - 2:3.10.3-5.2 +- Backport several CVE fixes + Resolves: RHEL-147912, RHEL-148815, RHEL-148859, RHEL-148892, RHEL-148973 + * Tue Jan 27 2026 Ondrej Holy - 2:3.10.3-5.1 - Backport several CVE fixes Resolves: RHEL-142413, RHEL-142397, RHEL-142381, RHEL-142365, RHEL-142349 diff --git a/utils-smartcard-add-length-validity-checks.patch b/utils-smartcard-add-length-validity-checks.patch new file mode 100644 index 0000000..55527c8 --- /dev/null +++ b/utils-smartcard-add-length-validity-checks.patch @@ -0,0 +1,81 @@ +From dc7bbfec41350c7cd3465d15f9facd8f9e2b0f20 Mon Sep 17 00:00:00 2001 +From: akallabeth +Date: Sun, 11 Jan 2026 09:03:57 +0100 +Subject: [PATCH] [utils,smartcard] add length validity checks + +Backport of commit 57c5647d98c2a026de8b681159cb188ca0439ef8. + +Co-Authored-By: Cursor +--- + libfreerdp/utils/smartcard_pack.c | 27 +++++++++++++++++++++------ + 1 file changed, 21 insertions(+), 6 deletions(-) + +diff --git a/libfreerdp/utils/smartcard_pack.c b/libfreerdp/utils/smartcard_pack.c +index 0ae0aff2c..52165def4 100644 +--- a/libfreerdp/utils/smartcard_pack.c ++++ b/libfreerdp/utils/smartcard_pack.c +@@ -97,8 +97,8 @@ static BOOL smartcard_ndr_pointer_read_(wStream* s, UINT32* index, UINT32* ptr, + return TRUE; + } + +-static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t elementSize, +- ndr_ptr_t type) ++static LONG smartcard_ndr_read_ex(wStream* s, BYTE** data, size_t min, ++ size_t elementSize, ndr_ptr_t type, size_t* plen) + { + size_t len = 0; + size_t offset = 0; +@@ -107,6 +107,9 @@ static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t eleme + size_t required = 0; + + *data = NULL; ++ if (plen) ++ *plen = 0; ++ + switch (type) + { + case NDR_PTR_FULL: +@@ -181,11 +184,20 @@ static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t eleme + if (!r) + return SCARD_E_NO_MEMORY; + Stream_Read(s, r, len); +- smartcard_unpack_read_size_align(s, len, 4); ++ const LONG pad = smartcard_unpack_read_size_align(s, len, 4); ++ len += (size_t)pad; + *data = r; ++ if (plen) ++ *plen = len; + return STATUS_SUCCESS; + } + ++static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t elementSize, ++ ndr_ptr_t type) ++{ ++ return smartcard_ndr_read_ex(s, data, min, elementSize, type, NULL); ++} ++ + static BOOL smartcard_ndr_pointer_write(wStream* s, UINT32* index, DWORD length) + { + const UINT32 ndrPtr = 0x20000 + (*index) * 4; +@@ -3207,12 +3219,15 @@ LONG smartcard_unpack_set_attrib_call(wStream* s, SetAttrib_Call* call) + + if (ndrPtr) + { +- // TODO: call->cbAttrLen was larger than the pointer value. +- // TODO: Maybe need to refine the checks? +- status = smartcard_ndr_read(s, &call->pbAttr, 0, 1, NDR_PTR_SIMPLE); ++ size_t len = 0; ++ status = smartcard_ndr_read_ex(s, &call->pbAttr, 0, 1, NDR_PTR_SIMPLE, &len); + if (status != SCARD_S_SUCCESS) + return status; ++ if (call->cbAttrLen > len) ++ call->cbAttrLen = (DWORD)len; + } ++ else ++ call->cbAttrLen = 0; + smartcard_trace_set_attrib_call(call); + return SCARD_S_SUCCESS; + } +-- +2.52.0 +