OS X Yosemite bug: SCardTransmit (pioSendPci not checked)
This is part of the series: "OS X Yosemite and smart cards: known bugs".
SCardTransmit
SCardTransmit() fails to detect wrong value forpioSendPci
parameter.If you use NULL for
pioSendPci
parameter then you get a crash (Segmentation fault: 11) of the application instead of getting the error 0x80100004
that is SCARD_E_INVALID_PARAMETER
.See also
Apple bug report #19231406 "PC/SC function SCardTransmit: pioSendPci not checked".Sample code
#include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef __APPLE__ #include <PCSC/winscard.h> #include <PCSC/wintypes.h> #else #include <winscard.h> #endif int main(int argc, const char * argv[]) { SCARDCONTEXT hContext; LPSTR mszReaders; DWORD err = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); if (err != SCARD_S_SUCCESS) { printf("ScardEstablishedContext : %08x\n",err); return -1; } DWORD cchReaders = 0; err = SCardListReaders(hContext, "SCard$AllReaders", NULL, &cchReaders); if (err != 0) { printf("ScardListReaders : %08x\n",err); return -1; } mszReaders = calloc(cchReaders, sizeof(char)); if (!mszReaders) { printf("calloc\n"); return -1; } err = SCardListReaders(hContext,"SCard$AllReaders", mszReaders, &cchReaders); if (err != SCARD_S_SUCCESS) { printf("ScardListReaders : %08x\n",err); return -1; } printf("Reader : %s\n", mszReaders); SCARDHANDLE hCard; DWORD dwActiveProtocol; err = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); unsigned char cmd[] = {0, 0, 0, 0, 0}; unsigned char resp[255]; DWORD resp_len = sizeof resp; err = SCardTransmit(hCard, NULL, cmd, sizeof cmd, NULL, resp, &resp_len); if (err != SCARD_S_SUCCESS) { printf("ScardTransmit : %08x\n",err); return -1; } SCardDisconnect(hCard, SCARD_LEAVE_CARD); SCardReleaseContext(hContext); return 0; }
Result (on Yosemite)
$ CFLAGS="-framework PCSC" make main cc -framework PCSC main.c -o main
$ ./main Reader : Gemalto PC Twin Reader Segmentation fault: 11
$ lldb ./main (lldb) target create "./main" Current executable set to './main' (x86_64). (lldb) r Process 6169 launched: './main' (x86_64) Reader : Gemalto PC Twin Reader Process 6169 stopped * thread #1: tid = 0x7472a, 0x0000000100004b6d PCSC`__SCardTransmit_block_invoke + 17, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0) frame #0: 0x0000000100004b6d PCSC`__SCardTransmit_block_invoke + 17 PCSC`__SCardTransmit_block_invoke + 17: -> 0x100004b6d: movl (%rax), %edx 0x100004b6f: leaq 0x6901(%rip), %rsi ; "proto" 0x100004b76: movq %r14, %rdi 0x100004b79: callq 0x10000b0c2 ; symbol stub for: xpc_dictionary_set_uint64
Expected result (on Debian)
CFLAGS=`pkg-config --cflags libpcsclite` LDFLAGS=`pkg-config --libs libpcsclite` make main
$ ./main Reader : Gemalto PC Twin Reader (70D7E2EE) 00 00 ScardTransmit : 80100004