scd: Fix possible assertion in close_pcsc_reader.

* scd/apdu.c (close_pcsc_reader): Don't ref-count if the context is
invalid.
(open_pcsc_reader): Compare the context against -1 which is our
indicator for an invalid context.
--

I got a crash report for Windows:

  DBG: chan_0x000000a4 <- RESTART
  DBG: chan_0x000000a4 -> OK
  DBG: chan_0x000000a4 <- SERIALNO
  DBG: open_pcsc_reader(portstr=(null))
  reader slot 0: not connected
  DBG: open_pcsc_reader => slot=0
  DBG: enter: apdu_connect: slot=0
  pcsc_connect failed: invalid PC/SC error code (0x6)
  reader slot 0: not connected
  DBG: leave: apdu_connect => sw=0x1000b
  DBG: enter: apdu_close_reader: slot=0
  DBG: enter: apdu_disconnect: slot=0
  DBG: leave: apdu_disconnect => sw=0x0
  Ohhhh jeeee: Assertion "pcsc.count > 0" in
    close_pcsc_reader failed (...2.2.28/scd/apdu.c:817)

no smartcard reader was connected but the box might sport a virtual
reader.  This patch should make it more robust.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2021-09-07 16:40:09 +02:00
parent 4b2cfec2dc
commit 192113552f
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
1 changed files with 12 additions and 6 deletions

View File

@ -90,7 +90,7 @@ typedef unsigned long pcsc_dword_t;
/* PC/SC context to access readers. Shared among all readers. */
static struct pcsc {
int count;
int count; /* Reference count - valid if .context != -1 */
long context;
} pcsc;
@ -814,11 +814,17 @@ static int
close_pcsc_reader (int slot)
{
(void)slot;
log_assert (pcsc.count > 0);
if (--pcsc.count == 0)
/* Note that we might be called via apdu_close_reader and we can't
* guarantee that we have not yet been called. */
if (pcsc.context != -1)
{
pcsc_release_context (pcsc.context);
pcsc.context = -1;
log_assert (pcsc.count > 0);
if (--pcsc.count == 0)
{
pcsc_release_context (pcsc.context);
pcsc.context = -1;
}
}
return 0;
}
@ -1199,7 +1205,7 @@ open_pcsc_reader (const char *portstr)
char *p;
size_t n;
if (pcsc.context < 0)
if (pcsc.context == -1)
if (pcsc_init () < 0)
return -1;