Package: pcscd Version: 1.4.3-1.1 Severity: important Tags: patch I am using pcsc with a USB CCID reader. Every so often it hangs. The reason is revealed by this backtrace, which was captured while it was hung:
#0 0x4012a321 in pthread_setcanceltype () from /lib/tls/libc.so.6 #1 0x4011a05f in syslog () from /lib/tls/libc.so.6 #2 0x0804d59e in log_msg (priority=1075286924, fmt=0xfffffffc <Address 0xfffffffc out of bounds>) at debuglog.c:74 #3 0x08050b43 in signal_reload (sig=10) at pcscdaemon.c:603 #4 <signal handler called> #5 0x4006e969 in __libc_sigaction () from /lib/tls/libc.so.6 #6 0x4006ea52 in sigaction () from /lib/tls/libc.so.6 #7 0x4011a481 in vsyslog () from /lib/tls/libc.so.6 #8 0x4011a05f in syslog () from /lib/tls/libc.so.6 #9 0x0804d59e in log_msg (priority=2, fmt=0x0) at debuglog.c:74 #10 0x0804e4c9 in EHStatusHandlerThread (rContext=0x80e8008) at eventhandler.c:301 #11 0x4002fb63 in start_thread () from /lib/tls/libpthread.so.0 #12 0x4011e18a in clone () from /lib/tls/libc.so.6 The other thread was also hung in syslog(). Notice what has happened here. syslog() was called within another call to syslog() - something I imagine syslog() doesn't expect. The underlying reason is how hotplug events are being handled. They are being processed by a signal() handler, which can happen at any time. The attached patch fixes the problem by forcing hotplug reload events to be handled synchronously. Unfortunately it probably isn't acceptable in its current form as it is very Unix dependant, and pcscd is obviously meant to be multi-platform. To make it multi-platform it would have to be a polling loop which is something I dislike, or your would have to abstract pthread_cond_wait in your thread_*.c libraries. -- System Information: Debian Release: 3.1 Architecture: i386 (i686) Kernel: Linux 2.6.17-8.1-lube-686-smp Locale: LANG=en_AU, LC_CTYPE=en_AU (charmap=ISO-8859-1) Versions of packages pcscd depends on: ii libasedrive-usb [pcsc 2.2-1 PC/SC driver for the Athena ASEDri ii libc6 2.3.2.ds1-22sarge6 GNU C Library: Shared libraries an ii libccid [pcsc-ifd-han 1.3.0-2.1 PC/SC driver for USB CCID smart ca ii libtowitoko2 [pcsc-if 2.0.7-3 Towitoko smartcard reader PCSC and ii libusb-0.1-4 2:0.1.12-2.1 userspace USB programming library ii lsb-base 3.0-11 Linux Standard Base 3.0 init scrip -- no debconf information
diff -Nur pcsc-lite-1.4.3/src/hotplug_libusb.c pcsc-lite-1.4.3-new/src/hotplug_libusb.c --- pcsc-lite-1.4.3/src/hotplug_libusb.c 2007-06-25 12:24:37.581244425 +1000 +++ pcsc-lite-1.4.3-new/src/hotplug_libusb.c 2007-06-25 12:27:20.222429918 +1000 @@ -56,6 +56,7 @@ static PCSCLITE_THREAD_T usbNotifyThread; static int driverSize = -1; static char AraKiriHotPlug = FALSE; +static int rescan_pipe[2] = { -1, -1 }; extern int HPForceReaderPolling; /* values of ifdCapabilities bits */ @@ -380,6 +381,7 @@ void HPEstablishUSBNotifications(void) { int i, do_polling; + char dummy; /* libusb default is /dev/bus/usb but the devices are not yet visible there * when a hotplug is requested */ @@ -411,10 +413,26 @@ do_polling = TRUE; } - while (do_polling) + if (do_polling) { - SYS_Sleep(HPForceReaderPolling); - HPRescanUsbBus(); + while (!AraKiriHotPlug) + { + SYS_Sleep(HPForceReaderPolling); + HPRescanUsbBus(); + } + } + else + { + pipe(rescan_pipe); + while (read(rescan_pipe[0], &dummy, sizeof(dummy)) > 0) + { + Log1(PCSC_LOG_INFO, "Reload serial configuration"); + HPRescanUsbBus(); + RFReCheckReaderConf(); + Log1(PCSC_LOG_INFO, "End reload serial configuration"); + } + close(rescan_pipe[0]); + rescan_pipe[0] = -1; } } @@ -439,6 +457,11 @@ LONG HPStopHotPluggables(void) { AraKiriHotPlug = TRUE; + if (rescan_pipe[1] >= 0) + { + close(rescan_pipe); + rescan_pipe[1] = -1; + } return 0; } @@ -535,8 +558,13 @@ void HPReCheckSerialReaders(void) { - HPRescanUsbBus(); - RFReCheckReaderConf(); + char dummy; + + if (rescan_pipe[1] >= 0) + { + dummy = 0; + write(rescan_pipe[1], &dummy, sizeof(dummy)); + } } #endif diff -Nur pcsc-lite-1.4.3/src/pcscdaemon.c pcsc-lite-1.4.3-new/src/pcscdaemon.c --- pcsc-lite-1.4.3/src/pcscdaemon.c 2007-06-25 11:41:29.845060776 +1000 +++ pcsc-lite-1.4.3-new/src/pcscdaemon.c 2007-06-25 12:25:25.093995305 +1000 @@ -558,24 +558,10 @@ void signal_reload(int sig) { - static int rescan_ongoing = FALSE; - if (AraKiri) return; - Log1(PCSC_LOG_INFO, "Reload serial configuration"); - if (rescan_ongoing) - { - Log1(PCSC_LOG_INFO, "Rescan already ongoing"); - return; - } - - rescan_ongoing = TRUE; - HPReCheckSerialReaders(); - - rescan_ongoing = FALSE; - Log1(PCSC_LOG_INFO, "End reload serial configuration"); } /* signal_reload */ void signal_trap(int sig)