From 65d59d3b3c2f630f2ea862687ecf5f95f8115244 Mon Sep 17 00:00:00 2001
From: Armin Novak <armin.novak@thincast.com>
Date: Sun, 15 Feb 2026 09:15:20 +0100
Subject: [PATCH] [utils,smartcard] check stream length on padding

When reading optional padding in smartcard channel check if padding is
actually there.

Origin: https://github.com/FreeRDP/FreeRDP/commit/65d59d3b3c2f630f2ea862687ecf5f95f8115244
---
 .../smartcard/client/smartcard_operations.c   |  5 ++--
 channels/smartcard/client/smartcard_pack.c    | 25 ++++++++++---------
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c
index 4639b17..649a8f8 100644
--- a/channels/smartcard/client/smartcard_operations.c
+++ b/channels/smartcard/client/smartcard_operations.c
@@ -2388,8 +2388,9 @@ LONG smartcard_irp_device_control_decode(SMARTCARD_DEVICE* smartcard,
 	    (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
 	{
 		offset = (RDPDR_DEVICE_IO_REQUEST_LENGTH + RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH);
-		smartcard_unpack_read_size_align(smartcard, irp->input,
-		                                 Stream_GetPosition(irp->input) - offset, 8);
+		if (smartcard_unpack_read_size_align(smartcard, irp->input,
+                                                 Stream_GetPosition(irp->input) - offset, 8) < 0)
+			return STATUS_INVALID_PARAMETER;
 	}
 
 	if (Stream_GetPosition(irp->input) < Stream_Length(irp->input))
diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c
index f70eb4e..d5e0374 100644
--- a/channels/smartcard/client/smartcard_pack.c
+++ b/channels/smartcard/client/smartcard_pack.c
@@ -1659,14 +1659,15 @@ void smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s,
 LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size,
                                       UINT32 alignment)
 {
-	size_t pad;
+	const size_t padsize = (size + alignment - 1) & ~(alignment - 1);
+	const size_t pad = padsize - size;
 	WINPR_UNUSED(smartcard);
-	pad = size;
-	size = (size + alignment - 1) & ~(alignment - 1);
-	pad = size - pad;
 
-	if (pad)
-		Stream_Seek(s, pad);
+	if (pad > 0)
+	{
+		if (!Stream_SafeSeek(s, pad))
+			return -1;
+	}
 
 	return (LONG)pad;
 }
@@ -1674,11 +1675,9 @@ LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, s
 LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size,
                                      UINT32 alignment)
 {
-	size_t pad;
 	WINPR_UNUSED(smartcard);
-	pad = size;
-	size = (size + alignment - 1) & ~(alignment - 1);
-	pad = size - pad;
+	const size_t padsize = (size + alignment - 1) & ~(alignment - 1);
+	const size_t pad = padsize - size;
 
 	if (pad)
 	{
@@ -3018,7 +3017,8 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra
 		call->pioSendPci->cbPciLength = (DWORD)(ioSendPci.cbExtraBytes + sizeof(SCARD_IO_REQUEST));
 		pbExtraBytes = &((BYTE*)call->pioSendPci)[sizeof(SCARD_IO_REQUEST)];
 		Stream_Read(s, pbExtraBytes, ioSendPci.cbExtraBytes);
-		smartcard_unpack_read_size_align(smartcard, s, ioSendPci.cbExtraBytes, 4);
+		if (smartcard_unpack_read_size_align(smartcard, s, ioSendPci.cbExtraBytes, 4) < 0)
+			return STATUS_INVALID_PARAMETER;
 	}
 	else
 	{
@@ -3118,7 +3118,8 @@ LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Tra
 			    (DWORD)(ioRecvPci.cbExtraBytes + sizeof(SCARD_IO_REQUEST));
 			pbExtraBytes = &((BYTE*)call->pioRecvPci)[sizeof(SCARD_IO_REQUEST)];
 			Stream_Read(s, pbExtraBytes, ioRecvPci.cbExtraBytes);
-			smartcard_unpack_read_size_align(smartcard, s, ioRecvPci.cbExtraBytes, 4);
+			if (smartcard_unpack_read_size_align(smartcard, s, ioRecvPci.cbExtraBytes, 4) < 0)
+				return STATUS_INVALID_PARAMETER;
 		}
 		else
 		{
-- 
2.52.0