-
-
Notifications
You must be signed in to change notification settings - Fork 92
Description
Describe the bug
After updating to current versions of pcscd, ccid and libusb I encountered a steady memory leak. In my case the leak was in the range of 10-40 MB each day.
The actual problem stems from the fact that pcscd is calling libusb_init() with the default libusb-context, while ccid is calling libusb_init() with a special context. While this is not illegal to do (afaik) with newer libusb-versions it causes that memory allocated in libusb-function usbi_add_event_source() will not be freed for the libusb_context that was created first. At some point libusb was changed that the memory allocated there will not be freed in usbi_remove_event_source(), but later on when either the libusb_context is destroyed (which never happens in my case) or when an event occurs. But events only occur on the second libusb_context and never on the first one.
I applied this patch to ccid and the memory leak disappeared. Though I guess this would cause trouble when libusb <= 1.0.8 would be used.
The auto-formating here seems to clash with +/- from diff so I had to add some "escape slashes".
diff --git a/src/ccid_usb.c b/src/ccid_usb.c
index 17f1296..573019d 100644
--- a/src/ccid_usb.c
+++ b/src/ccid_usb.c
@@ -59,8 +59,9 @@
/* Using the default libusb context */
/* does not work for libusb <= 1.0.8 */
-/* #define ctx NULL */
-static libusb_context *ctx = NULL;
+#define ctx NULL
+/*static libusb_context *ctx = NULL;*/
#define CCID_INTERRUPT_SIZE 8
@@ -193,9 +194,6 @@ static void close_libusb_if_needed(void)
{
bool to_exit = true;
- if (NULL == ctx)
- return;
-
/* if at least 1 reader is still in use we do not exit libusb */
for (int i=0; i<CCID_DRIVER_MAX_READERS; i++)
{
@@ -207,7 +205,6 @@ static void close_libusb_if_needed(void)
{
DEBUG_INFO1("libusb_exit");
libusb_exit(ctx);
- ctx = NULL;
}
} /* close_libusb_if_needed */
@@ -350,15 +347,12 @@ status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
GET_KEY("ifdProductString", values)
GET_KEY("Copyright", values)
- if (NULL == ctx)
+ rv = libusb_init(ctx);
+ if (rv != 0)
{
- rv = libusb_init(&ctx);
- if (rv != 0)
- {
- DEBUG_CRITICAL2("libusb_init failed: %s", libusb_error_name(rv));
- return_value = STATUS_UNSUCCESSFUL;
- goto end1;
- }
+ DEBUG_CRITICAL2("libusb_init failed: %s", libusb_error_name(rv));
+ return_value = STATUS_UNSUCCESSFUL;
+ goto end1;
}
#define GET_KEYS(key, values) \To Reproduce
pcscd is started with the following arguments:
-S --error --foreground -c
Versions:
- ccid version 1.6.2 (but should be the same with current master)
- pcsc-lite version 2.3.3
- libusb version 1.0.29
- pcscd -v
pcsc-lite version 2.2.0
Copyright (C) 1999-2002 by David Corcoran corcoran@musclecard.com.
Copyright (C) 2001-2024 by Ludovic Rousseau ludovic.rousseau@free.fr.
Copyright (C) 2003-2004 by Damien Sauveron sauveron@labri.fr.
Report bugs to pcsclite-muscle@lists.infradead.org.
Enabled features: Linux x86_64-pc-linux-gnu serial usb libusb usbdropdir=/usr/lib/pcsc/drivers ipcdir=/var/run filter configdir=//etc/reader.conf.d
MAX_READERNAME: 128, PCSCLITE_MAX_READERS_CONTEXTS: 16
Platform:
- Custom OS
- Does not actually require a smartcard (The problem also exists with softtokens being used)
Log:
The only syslog-message produces by pcscd is the following, but I guess this might just be because it was too early after boot to try and access USB. The daemon still works after that.
pcscd: hotplug_libusb.c:470:HPEstablishUSBNotifications() libusb_init failed: LIBUSB_ERROR_OTHER