diff --git a/libfreerdp/utils/smartcard_call.c b/libfreerdp/utils/smartcard_call.c index a0d980452..f6111faaa 100644 --- a/libfreerdp/utils/smartcard_call.c +++ b/libfreerdp/utils/smartcard_call.c @@ -192,7 +192,7 @@ static LONG smartcard_ListReaderGroupsA_Call(scard_call_context* smartcard, wStr cchGroups = SCARD_AUTOALLOCATE; ret.ReturnCode = wrap(smartcard, SCardListReaderGroupsA, operation->hContext, (LPSTR)&mszGroups, &cchGroups); - if (cchGroups == SCARD_AUTOALLOCATE) + if ((ret.ReturnCode == SCARD_S_SUCCESS) && (cchGroups == SCARD_AUTOALLOCATE)) return SCARD_F_UNKNOWN_ERROR; ret.msz = (BYTE*)mszGroups; @@ -224,7 +224,7 @@ static LONG smartcard_ListReaderGroupsW_Call(scard_call_context* smartcard, wStr cchGroups = SCARD_AUTOALLOCATE; status = ret.ReturnCode = wrap(smartcard, SCardListReaderGroupsW, operation->hContext, (LPWSTR)&mszGroups, &cchGroups); - if (cchGroups == SCARD_AUTOALLOCATE) + if ((ret.ReturnCode == SCARD_S_SUCCESS) && (cchGroups == SCARD_AUTOALLOCATE)) return SCARD_F_UNKNOWN_ERROR; ret.msz = (BYTE*)mszGroups; @@ -879,7 +879,7 @@ static LONG smartcard_GetReaderIcon_Call(scard_call_context* smartcard, wStream* ret.ReturnCode = wrap(smartcard, SCardGetReaderIconW, operation->hContext, call->szReaderName, (LPBYTE)&ret.pbData, &ret.cbDataLen); scard_log_status_error(TAG, "SCardGetReaderIconW", ret.ReturnCode); - if (ret.cbDataLen == SCARD_AUTOALLOCATE) + if ((ret.ReturnCode == SCARD_S_SUCCESS) && (ret.cbDataLen == SCARD_AUTOALLOCATE)) return SCARD_F_UNKNOWN_ERROR; status = smartcard_pack_get_reader_icon_return(out, &ret); @@ -1256,7 +1256,7 @@ static LONG smartcard_StatusA_Call(scard_call_context* smartcard, wStream* out, &ret.dwState, &ret.dwProtocol, cbAtrLen ? (BYTE*)&ret.pbAtr : NULL, &cbAtrLen); scard_log_status_error(TAG, "SCardStatusA", status); - if (cchReaderLen == SCARD_AUTOALLOCATE) + if ((ret.ReturnCode == SCARD_S_SUCCESS) && (cchReaderLen == SCARD_AUTOALLOCATE)) return SCARD_F_UNKNOWN_ERROR; if (status == SCARD_S_SUCCESS) @@ -1311,7 +1311,7 @@ static LONG smartcard_StatusW_Call(scard_call_context* smartcard, wStream* out, call->fmszReaderNamesIsNULL ? NULL : (LPWSTR)&mszReaderNames, &ret.cBytes, &ret.dwState, &ret.dwProtocol, (BYTE*)&ret.pbAtr, &cbAtrLen); scard_log_status_error(TAG, "SCardStatusW", status); - if (ret.cBytes == SCARD_AUTOALLOCATE) + if ((ret.ReturnCode == SCARD_S_SUCCESS) && (ret.cBytes == SCARD_AUTOALLOCATE)) return SCARD_F_UNKNOWN_ERROR; if (status == SCARD_S_SUCCESS) @@ -1443,7 +1443,7 @@ static LONG smartcard_GetAttrib_Call(scard_call_context* smartcard, wStream* out ret.ReturnCode = wrap(smartcard, SCardGetAttrib, operation->hCard, call->dwAttrId, pbAttr, &cbAttrLen); scard_log_status_error(TAG, "SCardGetAttrib", ret.ReturnCode); - if (cbAttrLen == SCARD_AUTOALLOCATE) + if ((ret.ReturnCode == SCARD_S_SUCCESS) && (cbAttrLen == SCARD_AUTOALLOCATE)) return SCARD_F_UNKNOWN_ERROR; ret.cbAttrLen = cbAttrLen; diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 116d79406..bee6e242c 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -2407,28 +2407,25 @@ static LONG WINAPI PCSC_SCardGetAttrib_Internal(SCARDHANDLE hCard, DWORD dwAttrI static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen) { - size_t length = 0; char* namePCSC = NULL; char* pbAttrA = NULL; - DWORD cbAttrLen = 0; - WCHAR* pbAttrW = NULL; - SCARDCONTEXT hContext = 0; - LONG status = SCARD_S_SUCCESS; - hContext = PCSC_GetCardContextFromHandle(hCard); + SCARDCONTEXT hContext = PCSC_GetCardContextFromHandle(hCard); if (!hContext) return SCARD_E_INVALID_HANDLE; if (!pcbAttrLen) return SCARD_E_INVALID_PARAMETER; - cbAttrLen = *pcbAttrLen; + const DWORD cbAttrLen = *pcbAttrLen; *pcbAttrLen = SCARD_AUTOALLOCATE; - status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A, - (LPBYTE)&pbAttrA, pcbAttrLen); + LONG status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A, + (LPBYTE)&pbAttrA, pcbAttrLen); if (status != SCARD_S_SUCCESS) { + WCHAR* pbAttrW = NULL; + *pcbAttrLen = SCARD_AUTOALLOCATE; status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W, (LPBYTE)&pbAttrW, pcbAttrLen); @@ -2441,7 +2438,7 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA } else { - namePCSC = _strdup(pbAttrA); + namePCSC = strndup(pbAttrA, *pcbAttrLen); if (!namePCSC) return SCARD_E_NO_MEMORY; @@ -2449,19 +2446,19 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA PCSC_SCardFreeMemory_Internal(hContext, pbAttrA); } - length = strlen(namePCSC); + size_t length = strnlen(namePCSC, *pcbAttrLen); if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W) { size_t size = 0; - WCHAR* friendlyNameW = ConvertUtf8ToWCharAlloc(namePCSC, &size); + WCHAR* friendlyNameW = ConvertUtf8NToWCharAlloc(namePCSC, length, &size); /* length here includes null terminator */ if (!friendlyNameW) status = SCARD_E_NO_MEMORY; else { - length = size; + length = size + 1; if (cbAttrLen == SCARD_AUTOALLOCATE) { @@ -2472,14 +2469,13 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA } else { - if ((length * 2) > cbAttrLen) + const size_t wlen = length * sizeof(WCHAR); + *pcbAttrLen = WINPR_ASSERTING_INT_CAST(uint32_t, wlen); + if ((wlen > cbAttrLen) && pbAttr) status = SCARD_E_INSUFFICIENT_BUFFER; - else - { - WINPR_ASSERT(length <= UINT32_MAX / sizeof(WCHAR)); - CopyMemory(pbAttr, (BYTE*)friendlyNameW, (length * sizeof(WCHAR))); - *pcbAttrLen = (UINT32)length * sizeof(WCHAR); - } + else if (pbAttr) + CopyMemory(pbAttr, friendlyNameW, (length * sizeof(WCHAR))); + free(friendlyNameW); } } @@ -2487,6 +2483,7 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA } else { + length++; /* Include '\0' in length */ if (cbAttrLen == SCARD_AUTOALLOCATE) { *(CHAR**)pbAttr = namePCSC; @@ -2496,14 +2493,12 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA } else { - if ((length + 1) > cbAttrLen) + *pcbAttrLen = WINPR_ASSERTING_INT_CAST(uint32_t, length); + if ((length > cbAttrLen) && pbAttr) status = SCARD_E_INSUFFICIENT_BUFFER; - else - { - CopyMemory(pbAttr, namePCSC, length + 1); - WINPR_ASSERT(length <= UINT32_MAX); - *pcbAttrLen = (UINT32)length; - } + else if (pbAttr) + CopyMemory(pbAttr, namePCSC, length); + free(namePCSC); } } @@ -2550,8 +2545,7 @@ static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE if ((dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_A) || (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W)) { - status = PCSC_SCardGetAttrib_FriendlyName(hCard, dwAttrId, pbAttr, pcbAttrLen); - return status; + return PCSC_SCardGetAttrib_FriendlyName(hCard, dwAttrId, pbAttr, pcbAttrLen); } status = PCSC_SCardGetAttrib_Internal(hCard, dwAttrId, pbAttr, pcbAttrLen); @@ -2577,8 +2571,8 @@ static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE if (vendorName) { size_t len = strnlen(vendorName, *pcbAttrLen); - WINPR_ASSERT(len <= UINT32_MAX); - *pcbAttrLen = (DWORD)len; + WINPR_ASSERT(len < UINT32_MAX); + *pcbAttrLen = (DWORD)len + 1; } else *pcbAttrLen = 0; @@ -2587,7 +2581,6 @@ static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE } else { - if (dwAttrId == SCARD_ATTR_CURRENT_PROTOCOL_TYPE) { if (!pcbAttrLenAlloc) @@ -2601,10 +2594,11 @@ static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE if (status == SCARD_S_SUCCESS) { - if (cbAttrLen < sizeof(DWORD)) + if ((cbAttrLen < sizeof(DWORD)) && pbAttr) return SCARD_E_INSUFFICIENT_BUFFER; - *(DWORD*)pbAttr = PCSC_ConvertProtocolsToWinSCard(dwProtocol); + if (pbAttr) + *(DWORD*)pbAttr = PCSC_ConvertProtocolsToWinSCard(dwProtocol); *pcbAttrLen = sizeof(DWORD); } } @@ -2616,11 +2610,12 @@ static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE UINT32 channelType = 0x20; /* USB */ UINT32 channelNumber = 0; - if (cbAttrLen < sizeof(DWORD)) + if ((cbAttrLen < sizeof(DWORD)) && pbAttr) return SCARD_E_INSUFFICIENT_BUFFER; status = SCARD_S_SUCCESS; - *(DWORD*)pbAttr = (channelType << 16u) | channelNumber; + if (pbAttr) + *(DWORD*)pbAttr = (channelType << 16u) | channelNumber; *pcbAttrLen = sizeof(DWORD); } }