diff --git a/scd/apdu.c b/scd/apdu.c index 07df9fea9..a343307e7 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -367,7 +367,8 @@ unlock_slot (int slot) /* Find an unused reader slot for PORTSTR and put it into the reader - table. Return -1 on error or the index into the reader table. */ + table. Return -1 on error or the index into the reader table. + Acquire slot's lock on successful return. Caller needs to unlock it. */ static int new_reader_slot (void) { @@ -394,6 +395,11 @@ new_reader_slot (void) reader_table[reader].lock_initialized = 1; } #endif /*USE_GNU_PTH*/ + if (lock_slot (reader)) + { + log_error ("error locking mutex: %s\n", strerror (errno)); + return -1; + } reader_table[reader].connect_card = NULL; reader_table[reader].disconnect_card = NULL; reader_table[reader].close_reader = NULL; @@ -675,6 +681,7 @@ open_ct_reader (int port) log_error ("apdu_open_ct_reader failed on port %d: %s\n", port, ct_error_string (rc)); reader_table[reader].used = 0; + unlock_slot (reader); return -1; } @@ -696,6 +703,7 @@ open_ct_reader (int port) reader_table[reader].keypad_modify = NULL; dump_reader_status (reader); + unlock_slot (reader); return reader; } @@ -1701,6 +1709,7 @@ open_pcsc_reader_direct (const char *portstr) log_error ("pcsc_establish_context failed: %s (0x%lx)\n", pcsc_error_string (err), err); reader_table[slot].used = 0; + unlock_slot (slot); if (err == 0x8010001d) pcsc_no_service = 1; return -1; @@ -1717,6 +1726,7 @@ open_pcsc_reader_direct (const char *portstr) log_error ("error allocating memory for reader list\n"); pcsc_release_context (reader_table[slot].pcsc.context); reader_table[slot].used = 0; + unlock_slot (slot); return -1 /*SW_HOST_OUT_OF_CORE*/; } err = pcsc_list_readers (reader_table[slot].pcsc.context, @@ -1729,6 +1739,7 @@ open_pcsc_reader_direct (const char *portstr) pcsc_release_context (reader_table[slot].pcsc.context); reader_table[slot].used = 0; xfree (list); + unlock_slot (slot); return -1; } @@ -1755,6 +1766,7 @@ open_pcsc_reader_direct (const char *portstr) log_error ("error allocating memory for reader name\n"); pcsc_release_context (reader_table[slot].pcsc.context); reader_table[slot].used = 0; + unlock_slot (slot); return -1; } strcpy (reader_table[slot].rdrname, portstr? portstr : list); @@ -1774,6 +1786,7 @@ open_pcsc_reader_direct (const char *portstr) reader_table[slot].dump_status_reader = dump_pcsc_reader_status; dump_reader_status (slot); + unlock_slot (slot); return slot; } #endif /*!NEED_PCSC_WRAPPER */ @@ -1821,6 +1834,7 @@ open_pcsc_reader_wrapped (const char *portstr) { log_error ("error creating a pipe: %s\n", strerror (errno)); slotp->used = 0; + unlock_slot (slot); return -1; } if (pipe (wp) == -1) @@ -1829,6 +1843,7 @@ open_pcsc_reader_wrapped (const char *portstr) close (rp[0]); close (rp[1]); slotp->used = 0; + unlock_slot (slot); return -1; } @@ -1841,6 +1856,7 @@ open_pcsc_reader_wrapped (const char *portstr) close (wp[0]); close (wp[1]); slotp->used = 0; + unlock_slot (slot); return -1; } slotp->pcsc.pid = pid; @@ -1976,6 +1992,7 @@ open_pcsc_reader_wrapped (const char *portstr) pcsc_get_status (slot, &dummy_status); dump_reader_status (slot); + unlock_slot (slot); return slot; command_failed: @@ -1986,6 +2003,7 @@ open_pcsc_reader_wrapped (const char *portstr) kill (slotp->pcsc.pid, SIGTERM); slotp->pcsc.pid = (pid_t)(-1); slotp->used = 0; + unlock_slot (slot); /* There is no way to return SW. */ return -1; @@ -2422,6 +2440,7 @@ open_ccid_reader (const char *portstr) if (err) { slotp->used = 0; + unlock_slot (slot); return -1; } @@ -2456,6 +2475,7 @@ open_ccid_reader (const char *portstr) reader_table[slot].is_t0 = 0; dump_reader_status (slot); + unlock_slot (slot); return slot; } @@ -2694,6 +2714,7 @@ open_rapdu_reader (int portno, if (!slotp->rapdu.handle) { slotp->used = 0; + unlock_slot (slot); return -1; } @@ -2748,12 +2769,14 @@ open_rapdu_reader (int portno, dump_reader_status (slot); rapdu_msg_release (msg); + unlock_slot (slot); return slot; failure: rapdu_msg_release (msg); rapdu_release (slotp->rapdu.handle); slotp->used = 0; + unlock_slot (slot); return -1; }