From d9c873dec38884119cbae309d24203f84ab1c6ac Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 12 Mar 2026 21:46:29 +0100 Subject: [PATCH] vpcd: added more input checking (#328) May fix unstability issues #326 #324 (cherry picked from commit 7c949d1ec0e40ca2aabf92192cdf9f66a4a7a0bf) --- .../win32/VivoKeySmartReader/PipeReader.cpp | 1 + .../win32/VivoKeySmartReader/Reader.cpp | 40 ++++++++++--------- .../win32/VivoKeySmartReader/TcpIpReader.cpp | 1 + .../win32/VivoKeySmartReader/VpcdReader.cpp | 1 + .../win32/VivoKeySmartReader/memory.cpp | 14 ++++--- .../win32/VivoKeySmartReader/memory.h | 6 +-- 6 files changed, 37 insertions(+), 26 deletions(-) diff --git a/virtualsmartcard/win32/VivoKeySmartReader/PipeReader.cpp b/virtualsmartcard/win32/VivoKeySmartReader/PipeReader.cpp index d9c8a60..cb264f9 100644 --- a/virtualsmartcard/win32/VivoKeySmartReader/PipeReader.cpp +++ b/virtualsmartcard/win32/VivoKeySmartReader/PipeReader.cpp @@ -126,6 +126,7 @@ bool PipeReader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) { } if (size==0) return false; + size=min(size,*ATRsize); if (!ReadFile(pipe,ATR,size,&read,NULL)) { pipe=NULL; return false; diff --git a/virtualsmartcard/win32/VivoKeySmartReader/Reader.cpp b/virtualsmartcard/win32/VivoKeySmartReader/Reader.cpp index 8ffb64f..df8b594 100644 --- a/virtualsmartcard/win32/VivoKeySmartReader/Reader.cpp +++ b/virtualsmartcard/win32/VivoKeySmartReader/Reader.cpp @@ -88,7 +88,7 @@ void Reader::IoSmartCardPower(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T ou } if (code==SCARD_COLD_RESET || code==SCARD_WARM_RESET) { BYTE ATR[100]; - DWORD ATRsize; + DWORD ATRsize=sizeof(ATR); if (!QueryATR(ATR,&ATRsize,true)) { pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0); @@ -114,7 +114,7 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ OutputDebugString(log); BYTE ATR[100]; - DWORD ATRsize; + DWORD ATRsize=sizeof(ATR); state=SCARD_SPECIFIC; if (!QueryATR(ATR,&ATRsize,true)) { @@ -200,7 +200,7 @@ void Reader::IoSmartCardTransmit(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T UNREFERENCED_PARAMETER(outBufSize); OutputDebugString(L"[VivoKeySmartReader][TRSM]IOCTL_SMARTCARD_TRANSMIT"); SCARD_IO_REQUEST *scardRequest=NULL; - int scardRequestSize=0; + SIZE_T scardRequestSize=0; BYTE *RAPDU=NULL; int RAPDUSize=0; if (!getBuffer(pRequest,(void **)&scardRequest,&scardRequestSize) @@ -255,8 +255,9 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI if (rpcType==0) { PipeReader *pipe=(PipeReader *)this; OutputDebugString(L"[VivoKeySmartReader][GATT]PIPE_NAME"); - sprintf(temp,"%S",pipe->pipeName); - setString(device,pRequest,(char*)temp,(int)outBufSize); + sprintf(temp,"%.*S",(int)sizeof(temp),pipe->pipeName); + temp[sizeof(temp)-1] = '\0'; + setString(device,pRequest,(char*)temp,outBufSize); } else { SectionLocker lock(device->m_RequestLock); @@ -268,8 +269,9 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI if (rpcType==0) { PipeReader *pipe=(PipeReader *)this; OutputDebugString(L"[VivoKeySmartReader][GATT]EVENT_PIPE_NAME"); - sprintf(temp,"%S",pipe->pipeEventName); - setString(device,pRequest,(char*)temp,(int)outBufSize); + sprintf(temp,"%.*S",(int)sizeof(temp),pipe->pipeEventName); + temp[sizeof(temp)-1] = '\0'; + setString(device,pRequest,(char*)temp,outBufSize); } else { SectionLocker lock(device->m_RequestLock); @@ -320,28 +322,30 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI return; case SCARD_ATTR_VENDOR_NAME: OutputDebugString(L"[VivoKeySmartReader][GATT]SCARD_ATTR_VENDOR_NAME"); - setString(device,pRequest,vendorName,(int)outBufSize); + setString(device,pRequest,vendorName,outBufSize); return; case SCARD_ATTR_VENDOR_IFD_TYPE: OutputDebugString(L"[VivoKeySmartReader][GATT]SCARD_ATTR_VENDOR_IFD_TYPE"); - setString(device,pRequest,vendorIfdType,(int)outBufSize); + setString(device,pRequest,vendorIfdType,outBufSize); return; case SCARD_ATTR_DEVICE_UNIT: OutputDebugString(L"[VivoKeySmartReader][GATT]SCARD_ATTR_DEVICE_UNIT"); setInt(device,pRequest,deviceUnit); return; case SCARD_ATTR_ATR_STRING: - OutputDebugString(L"[VivoKeySmartReader][GATT]SCARD_ATTR_ATR_STRING"); - BYTE ATR[100]; - DWORD ATRsize; - if (!QueryATR(ATR,&ATRsize)) { - SectionLocker lock(device->m_RequestLock); - pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0); + OutputDebugString(L"[VivoKeySmartReader][GATT]SCARD_ATTR_ATR_STRING"); + BYTE ATR[100]; + DWORD ATRsize=sizeof(ATR); + if (!QueryATR(ATR,&ATRsize)) + { + SectionLocker lock(device->m_RequestLock); + pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0); + return; + } + setBuffer(device,pRequest,ATR,ATRsize); return; } - setBuffer(device,pRequest,ATR,ATRsize); - return; case SCARD_ATTR_CURRENT_PROTOCOL_TYPE: OutputDebugString(L"[VivoKeySmartReader][GATT]SCARD_ATTR_CURRENT_PROTOCOL_TYPE"); setInt(device,pRequest,protocol); // T=0 or T=1 @@ -377,7 +381,7 @@ bool Reader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) { bool Reader::initProtocols() { // ask ATR to determine available protocols BYTE ATR[100]; - DWORD ATRsize=100; + DWORD ATRsize=sizeof(ATR); availableProtocol=0; if (QueryATR(ATR,&ATRsize,true)) { diff --git a/virtualsmartcard/win32/VivoKeySmartReader/TcpIpReader.cpp b/virtualsmartcard/win32/VivoKeySmartReader/TcpIpReader.cpp index 2e4d4f0..b33b25f 100644 --- a/virtualsmartcard/win32/VivoKeySmartReader/TcpIpReader.cpp +++ b/virtualsmartcard/win32/VivoKeySmartReader/TcpIpReader.cpp @@ -107,6 +107,7 @@ bool TcpIpReader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) { } if (size==0) return false; + size=min(size,*ATRsize); if ((read=recv(AcceptSocket,(char*)ATR,size,MSG_WAITALL))<=0) { ::shutdown(AcceptSocket,SD_BOTH); AcceptSocket=NULL; diff --git a/virtualsmartcard/win32/VivoKeySmartReader/VpcdReader.cpp b/virtualsmartcard/win32/VivoKeySmartReader/VpcdReader.cpp index f77fb94..af25dc3 100644 --- a/virtualsmartcard/win32/VivoKeySmartReader/VpcdReader.cpp +++ b/virtualsmartcard/win32/VivoKeySmartReader/VpcdReader.cpp @@ -70,6 +70,7 @@ bool VpcdReader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) { if (atr_len > 0) { /* TODO do length checking on length of ATR when ATRsize is * correctly initialized by Reader.cpp */ + atr_len = min(atr_len, *ATRsize); memcpy(ATR, atr, atr_len); *ATRsize = atr_len; free(atr); diff --git a/virtualsmartcard/win32/VivoKeySmartReader/memory.cpp b/virtualsmartcard/win32/VivoKeySmartReader/memory.cpp index be08da3..4cedbe4 100644 --- a/virtualsmartcard/win32/VivoKeySmartReader/memory.cpp +++ b/virtualsmartcard/win32/VivoKeySmartReader/memory.cpp @@ -1,7 +1,7 @@ #include "memory.h" #include "SectionLocker.h" -bool getBuffer(IWDFIoRequest* pRequest,void **buffer,int *bufferLen) { +bool getBuffer(IWDFIoRequest* pRequest,void **buffer,SIZE_T *bufferLen) { IWDFMemory *inmem=NULL; pRequest->GetInputMemory(&inmem); if (inmem==NULL) { @@ -20,13 +20,13 @@ bool getBuffer(IWDFIoRequest* pRequest,void **buffer,int *bufferLen) { memcpy(out,data,size); (*buffer)=out; } - (*bufferLen)=(int)size; + (*bufferLen)=size; inmem->Release(); return true; } } -void setBuffer(CMyDevice *device,IWDFIoRequest* pRequest,void *result,int inSize) { +void setBuffer(CMyDevice *device,IWDFIoRequest* pRequest,void *result,SIZE_T inSize) { IWDFMemory *outmem=NULL; pRequest->GetOutputMemory (&outmem); if (outmem==NULL) { @@ -42,7 +42,7 @@ void setBuffer(CMyDevice *device,IWDFIoRequest* pRequest,void *result,int inSize } } -void setString(CMyDevice *device,IWDFIoRequest* pRequest,char *result,int outSize) { +void setString(CMyDevice *device,IWDFIoRequest* pRequest,char *result,SIZE_T outSize) { IWDFMemory *outmem=NULL; pRequest->GetOutputMemory (&outmem); if (outmem==NULL) { @@ -52,7 +52,7 @@ void setString(CMyDevice *device,IWDFIoRequest* pRequest,char *result,int outSiz } else { SectionLocker lock(device->m_RequestLock); - int size=min(outSize,(int)strlen(result)+1); + SIZE_T size=min(outSize,strlen(result)+1); outmem->CopyFromBuffer(0,result,size); outmem->Release(); pRequest->CompleteWithInformation(0,(SIZE_T)size); @@ -84,6 +84,10 @@ DWORD getInt(IWDFIoRequest* pRequest) { else { SIZE_T size; void *data=inmem->GetDataBuffer(&size); + if (sizeRelease(); return d; diff --git a/virtualsmartcard/win32/VivoKeySmartReader/memory.h b/virtualsmartcard/win32/VivoKeySmartReader/memory.h index 50b549c..55b3dc8 100644 --- a/virtualsmartcard/win32/VivoKeySmartReader/memory.h +++ b/virtualsmartcard/win32/VivoKeySmartReader/memory.h @@ -3,8 +3,8 @@ #include "device.h" -bool getBuffer(IWDFIoRequest* pRequest,void **buffer,int *bufferLen); -void setString(CMyDevice *device,IWDFIoRequest* pRequest,char *result,int outSize); -void setBuffer(CMyDevice *device,IWDFIoRequest* pRequest,void *result,int inSize); +bool getBuffer(IWDFIoRequest* pRequest,void **buffer,SIZE_T *bufferLen); +void setString(CMyDevice *device,IWDFIoRequest* pRequest,char *result,SIZE_T outSize); +void setBuffer(CMyDevice *device,IWDFIoRequest* pRequest,void *result,SIZE_T inSize); void setInt(CMyDevice *device,IWDFIoRequest* pRequest,DWORD result); DWORD getInt(IWDFIoRequest* pRequest);