Hello,
I would like to report an error message which valgrind throws the first time "SCardEstablishContext()" is called. The error message does not appear again when a second call to the function is done. Please have a look at the attached minimal example code. The program connects and disconnects to a smartcard two times. In order for the valgrind message to trigger, a smartcard has to be connected to the PC and the pcscd service has to be running. The code was linked with the newest stable release, 1.8.22. The code is compiled and linked on a FreeBSD system running FreeBSD 10.3 (AMD64), the executable is then copied to a pfsense Box which also runs FreeBSD 10.3 with the same pcscd version. It would be great if a developer could look at this and commit a fix for this message. Below is the exampleConnect.c example, the build command and the valgrind error log. Regards, Thomas Bajer Valgrind output: $ /usr/local/bin/valgrind --leak-check=full /root/example ==63949== Memcheck, a memory error detector ==63949== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==63949== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==63949== Command: /root/example ==63949== Establish context ==63949== Syscall param socketcall.connect(serv_addr..sa_len) points to uninitialised byte(s) ==63949== at 0x535555A: _connect (in /lib/libc.so.7) ==63949== by 0x57EDA65: ??? (in /lib/libthr.so.3) ==63949== by 0x4E309B9: ??? (in /usr/local/lib/libpcsclite.so.1.0.0) ==63949== by 0x4E2C20A: SCardEstablishContext (in /usr/local/lib/libpcsclite.so.1.0.0) ==63949== by 0x400AC2: connectToSmartcard (in /root/example) ==63949== by 0x400A1B: main (in /root/example) ==63949== Address 0x7ff0009d8 is on thread 1's stack ==63949== List readers Connect to card Smartcard connected! Disconnect card... Free reader... Release context... Establish context List readers Connect to card Smartcard connected! Disconnect card... Free reader... Release context... DONE! ==63949== ==63949== HEAP SUMMARY: ==63949== in use at exit: 5,368 bytes in 8 blocks ==63949== total heap usage: 26 allocs, 18 frees, 6,210 bytes allocated ==63949== ==63949== LEAK SUMMARY: ==63949== definitely lost: 0 bytes in 0 blocks ==63949== indirectly lost: 0 bytes in 0 blocks ==63949== possibly lost: 0 bytes in 0 blocks ==63949== still reachable: 5,368 bytes in 8 blocks ==63949== suppressed: 0 bytes in 0 blocks ==63949== Reachable blocks (those to which a pointer was found) are not shown. ==63949== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==63949== ==63949== For counts of detected and suppressed errors, rerun with: -v ==63949== Use --track-origins=yes to see where uninitialised values come from ==63949== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 0 from 0) Program code: /* * exampleConnect.c * * Created on: 19.07.2017 * Author: User */ /* compile command */ /* gcc -o example exampleConnect.c -I/usr/local/include/PCSC -lpcsclite -lusb */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> //#include <usb.h> #include <errno.h> #include <stdint.h> #ifdef __APPLE__ #include <PCSC/winscard.h> #include <PCSC/wintypes.h> #else #include <winscard.h> #endif int connectToSmartcard( SCARDCONTEXT *hContext, SCARDHANDLE *hCard, LPTSTR *mszReaders); void disconnectSmartcard(SCARDCONTEXT *hContext, SCARDHANDLE *hCard, LPTSTR *mszReaders); int main(int argc, char **argv) { SCARDCONTEXT hContext; SCARDHANDLE hCard; LPTSTR mszReaders; int ret = connectToSmartcard(&hContext, &hCard, &mszReaders); if(ret == 0) { disconnectSmartcard(&hContext, &hCard, &mszReaders); } ret = connectToSmartcard(&hContext, &hCard, &mszReaders); if(ret == 0) { disconnectSmartcard(&hContext, &hCard, &mszReaders); } printf("DONE!\n"); return ret; } int connectToSmartcard( SCARDCONTEXT *hContext, SCARDHANDLE *hCard, LPTSTR *mszReaders) { LONG rv = 0; DWORD dwReaders, dwActiveProtocol ; // Init context printf("Establish context\n"); rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, hContext); if (SCARD_S_SUCCESS != rv) { return -1; } // Get available smartcard readers #ifdef SCARD_AUTOALLOCATE dwReaders = SCARD_AUTOALLOCATE; printf("List readers\n"); rv = SCardListReaders(*hContext, NULL, (LPTSTR)mszReaders, &dwReaders); if (SCARD_S_SUCCESS != rv) { SCardReleaseContext(*hContext); return -1; } #else printf("List readers\n"); rv = SCardListReaders(*hContext, NULL, NULL, &dwReaders); if (SCARD_S_SUCCESS != rv) { SCardReleaseContext(*hContext); return -1; } printf("Allocate readers\n"); mszReaders = calloc(dwReaders, sizeof(char)); rv = SCardListReaders(*hContext, NULL, *mszReaders, &dwReaders); if(SCARD_S_SUCCESS != rv) { SCardFreeMemory(*hContext, mszReaders); SCardReleaseContext(*hContext); return -1; } #endif printf("Connect to card\n"); // Connect to smartcard rv = SCardConnect( *hContext, *mszReaders, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, hCard, &dwActiveProtocol); if (SCARD_S_SUCCESS != rv) { SCardFreeMemory(*hContext, *mszReaders); SCardReleaseContext(*hContext); return -1; } printf("Smartcard connected!\n"); return 0; } void disconnectSmartcard(SCARDCONTEXT *hContext, SCARDHANDLE *hCard, LPTSTR *mszReaders) { printf("Disconnect card...\n"); SCardDisconnect(*hCard, SCARD_LEAVE_CARD); printf("Free reader...\n"); #ifdef SCARD_AUTOALLOCATE SCardFreeMemory(*hContext, *mszReaders); #else free(*mszReaders); #endif printf("Release context...\n"); SCardReleaseContext(*hContext); // system("service pcscd onestop"); // printf("Smartcard disconnected!\n"); } -- Thomas Bajer Security Engineer _________________________________ PHYSEC GmbH Gebäude ID | Raum 05/409 Universitätsstraße 150 44801 Bochum, Germany Web: http://www.physec.de _______________________________________________ Pcsclite-muscle mailing list [hidden email] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle |
Hello,
I would like to report an error, which occurs, when using PCSC-lite for smartcard detection in C. It causes the smartcard to remain undetected, when the reader is disconnected. The current workaround is to restart the PCSC deamon at the beginning. In my application the removal of the reader is unavoidable, since I am using a USB token, which acts as a combination of a reader and a smartcard. Please have a look at the attached minimal example code. The program checks, whether a reader an a card are available, then connects to the smartcard. Afterwards, the smartcard is diconnected and the program waits until the smartcard is no longer physically connected. This process is being looped until the programm is aborted. The code was linked with the newest stable release, 1.8.22-1. The code is compiled and linked on a FreeBSD system running FreeBSD 10.3 (AMD64), the executable is then copied to a pfsense Box which also runs FreeBSD 10.3 with the same pcscd version. It would be great if a developer could look at this and commit a fix for this message. Below is the exampleReconnect.c example and the build command. Feel free to play around with it and to make use of the defines at the beginning of the code Regards, Thomas Bajer /* * exampleReconnect.c * * Created on: 20.07.2017 * Author: T. Bajer */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> //#include <usb.h> #include <errno.h> #include <stdint.h> #ifdef __APPLE__ #include <PCSC/winscard.h> #include <PCSC/wintypes.h> #else #include <winscard.h> #endif /* ############################################################################################ * #### BUILD COMMAND: #### * #### gcc -o example exampleReconnect.c -I/usr/local/include/PCSC -lpcsclite -lusb -Wall #### * ############################################################################################ */ /* Uncomment me for more details */ //#define SC_DEBUG /* Uncomment me to make it work */ //#define HOTFIX /* * Prototypes */ int connectToSmartcard( SCARDCONTEXT *hContext, SCARDHANDLE *hCard, LPTSTR *mszReaders); void disconnectSmartcard( SCARDCONTEXT *hContext, SCARDHANDLE *hCard, LPTSTR *mszReaders); void waitForSmartcardConnect(); void waitForSmartcardDisconnect(); /* * MAIN function */ int main(int argc, char **argv) { SCARDCONTEXT hContext; SCARDHANDLE hCard; LPTSTR mszReaders; printf("Smartcard detection started.\n"); for(;;) { printf("Waiting for smartcard connect...\n"); #ifdef HOTFIX system("service pcscd restart"); #endif waitForSmartcardConnect(); printf("Smartcard found.\n"); printf("Connecting to smartcard...\n"); if(connectToSmartcard(&hContext, &hCard, &mszReaders) == 0) { printf("Connecting successful!\n"); /* * Do SC stuff here */ printf("Disconnecting...\n"); disconnectSmartcard(&hContext, &hCard, &mszReaders); printf("Disconnected!\n"); } else { printf("CONNECT FAILED!\n"); } printf("Waiting for smartcard disconnect...\n"); waitForSmartcardDisconnect(); printf("Smartcard lost!\n"); } return 0; } /* * Implementations */ int connectToSmartcard( SCARDCONTEXT *hContext, SCARDHANDLE *hCard, LPTSTR *mszReaders) { LONG rv = 0; DWORD dwReaders, dwActiveProtocol ; // Init context printf("Establish context\n"); rv = SCardEstablishContext( SCARD_SCOPE_SYSTEM, NULL, NULL, hContext); if (SCARD_S_SUCCESS != rv) { return -1; } // Get available smartcard readers #ifdef SCARD_AUTOALLOCATE dwReaders = SCARD_AUTOALLOCATE; printf("List readers\n"); rv = SCardListReaders( *hContext, NULL, (LPTSTR)mszReaders, &dwReaders); if (SCARD_S_SUCCESS != rv) { SCardReleaseContext(*hContext); return -1; } #else printf("List readers\n"); rv = SCardListReaders( *hContext, NULL, NULL, &dwReaders); if (SCARD_S_SUCCESS != rv) { SCardReleaseContext(*hContext); return -1; } printf("Allocate readers\n"); mszReaders = calloc(dwReaders, sizeof(char)); rv = SCardListReaders( *hContext, NULL, *mszReaders, &dwReaders ); if(SCARD_S_SUCCESS != rv) { SCardFreeMemory( *hContext, mszReaders ); SCardReleaseContext( *hContext ); return -1; } #endif printf( "Connect to card\n" ); // Connect to smartcard rv = SCardConnect( *hContext, *mszReaders, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, hCard, &dwActiveProtocol ); if (SCARD_S_SUCCESS != rv) { SCardFreeMemory( *hContext, *mszReaders ); SCardReleaseContext( *hContext ); return -1; } printf( "Smartcard connected!\n" ); return 0; } void disconnectSmartcard( SCARDCONTEXT *hContext, SCARDHANDLE *hCard, LPTSTR *mszReaders) { printf("Disconnect card...\n"); SCardDisconnect( *hCard, SCARD_LEAVE_CARD ); printf("Free reader...\n"); #ifdef SCARD_AUTOALLOCATE SCardFreeMemory( *hContext, *mszReaders ); #else free( *mszReaders ); #endif printf( "Release context...\n" ); SCardReleaseContext( *hContext ); } int checkSmartcard( SCARDCONTEXT *hContext, SCARDHANDLE *hCard, LPTSTR *mszReaders) { LONG rv = 0; DWORD dwReaders, dwActiveProtocol; // Init context #ifdef SC_DEBUG printf("Establishing SC context...\n"); #endif rv = SCardEstablishContext( SCARD_SCOPE_SYSTEM, NULL, NULL, hContext); if (SCARD_S_SUCCESS != rv) { #ifdef SC_DEBUG printf("ERROR: Establishing SC context!\n"); #endif } // Get available smartcard readers #ifdef SCARD_AUTOALLOCATE if (SCARD_S_SUCCESS == rv) { dwReaders = SCARD_AUTOALLOCATE; #ifdef SC_DEBUG printf("Listing SC readers...\n"); #endif rv = SCardListReaders( *hContext, NULL, (LPTSTR)mszReaders, &dwReaders ); if (SCARD_S_SUCCESS != rv) { #ifdef SC_DEBUG printf("ERROR: Listing SC readers!\n"); #endif /* Max: this has to be given by value, not by pointer! (even if it doesn't make sense..) */ SCardReleaseContext(*hContext); } } #else if (SCARD_S_SUCCESS == rv) { #ifdef SC_DEBUG printf("Listing SC readers...\n"); #endif rv = SCardListReaders( *hContext, NULL, NULL, &dwReaders); if (SCARD_S_SUCCESS != rv) { #ifdef SC_DEBUG printf("ERROR: Listing SC readers!\n"); #endif SCardReleaseContext( *hContext ); } } if (SCARD_S_SUCCESS == rv) { #ifdef SC_DEBUG printf( "Listing SC readers...\n" ); #endif mszReaders = calloc( dwReaders, sizeof(char) ); rv = SCardListReaders( *hContext, NULL, *mszReaders, &dwReaders ); if(SCARD_S_SUCCESS != rv) { #ifdef SC_DEBUG printf( "ERROR: Listing SC readers!\n" ); #endif SCardFreeMemory( *hContext, *mszReaders ); SCardReleaseContext( *hContext ); } } #endif if (SCARD_S_SUCCESS == rv) { #ifdef SC_DEBUG printf( "Connecting to SC...\n" ); #endif rv = SCardConnect( *hContext, *mszReaders, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, hCard, &dwActiveProtocol); if (SCARD_S_SUCCESS != rv) { #ifdef SC_DEBUG printf("ERROR: Connecting to SC!\n"); #endif } } SCardFreeMemory(*hContext, *mszReaders); SCardReleaseContext(*hContext); fflush(stdout); return rv; } void waitForSmartcardConnect() { SCARDCONTEXT hContext; SCARDHANDLE hCard; LPTSTR mszReaders; while(checkSmartcard(&hContext, &hCard, &mszReaders) != 0) { sleep(1); } } void waitForSmartcardDisconnect() { SCARDCONTEXT hContext; SCARDHANDLE hCard; LPTSTR mszReaders; while(checkSmartcard(&hContext, &hCard, &mszReaders) == 0) { sleep(1); } } _______________________________________________ Pcsclite-muscle mailing list [hidden email] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle |
Hello, Please generate a pcscd trace as described at http://pcsclite.alioth.debian.org/pcsclite.html#support bye Dr. Ludovic Rousseau Le 21 juil. 2017 13:47, "Thomas Bajer" <[hidden email]> a écrit : Hello, _______________________________________________ Pcsclite-muscle mailing list [hidden email] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle |
In reply to this post by Thomas Bajer
2017-07-19 15:14 GMT+02:00 Thomas Bajer <[hidden email]>: -- Hello, Hello,
I can't reproduce your problem with a Debian stable system on amd64. I get: $ valgrind --leak-check=full ./sample ==4086== Memcheck, a memory error detector ==4086== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==4086== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info ==4086== Command: ./sample ==4086== Establish context List readers Connect to card Smartcard connected! Disconnect card... Free reader... Release context... Establish context List readers Connect to card Smartcard connected! Disconnect card... Free reader... Release context... DONE! ==4086== ==4086== HEAP SUMMARY: ==4086== in use at exit: 112 bytes in 4 blocks ==4086== total heap usage: 21 allocs, 17 frees, 1,922 bytes allocated ==4086== ==4086== LEAK SUMMARY: ==4086== definitely lost: 0 bytes in 0 blocks ==4086== indirectly lost: 0 bytes in 0 blocks ==4086== possibly lost: 0 bytes in 0 blocks ==4086== still reachable: 112 bytes in 4 blocks ==4086== suppressed: 0 bytes in 0 blocks ==4086== Reachable blocks (those to which a pointer was found) are not shown. ==4086== To see them, rerun with: --leak-check=full --show-leak-kinds=all ==4086== ==4086== For counts of detected and suppressed errors, rerun with: -v ==4086== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) Please rebuild pcsc-lite using this patch and try again: --- /tmp/lJqSB4_winscard_msg.c 2017-07-31 10:02:24.804416987 +0200 +++ src/winscard_msg.c 2017-07-31 09:59:09.565876305 +0200 @@ -130,6 +130,7 @@ INTERNAL int ClientSetupSession(uint32_t *pdwClientID = ret; socketName = getSocketName(); + memset(&svc_addr, 0, sizeof svc_addr); svc_addr.sun_family = AF_UNIX; strncpy(svc_addr.sun_path, socketName, sizeof(svc_addr.sun_path)); Bye Dr. Ludovic Rousseau
_______________________________________________ Pcsclite-muscle mailing list [hidden email] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle |
Free forum by Nabble | Edit this page |