1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-23 10:29:58 +01:00

scd: acquire lock in new_reader_slot.

* scd/apdu.c (new_reader_slot): Acquire lock.
  (open_ct_reader, open_pcsc_reader_direct, open_pcsc_reader_wrapped)
  (open_ccid_reader, open_rapdu_reader): Release lock.

--
Fixes a test case of:
   No libpcsclite1 installed.
   Run gpg-agent
   Run command "gpg-connect-agent learn /bye" with no card/token
   Sometimes it fails: ERR 100663356 Not supported <SCD>
   While it should be always: ERR 100663404 Card error <SCD>
This commit is contained in:
NIIBE Yutaka 2012-06-18 15:08:01 +09:00
parent 233b5ab1ad
commit 4f557cb9c2

View File

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