aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2021-09-07 14:40:09 +0000
committerWerner Koch <[email protected]>2021-09-07 14:40:09 +0000
commit192113552faa98f40cc91fe014ec55861474626c (patch)
treeca3908b8535bcc14fbfeabb16de3c019d54377b0
parentagent: Fix segv in GET_PASSPHRASE (regression) (diff)
downloadgnupg-192113552faa98f40cc91fe014ec55861474626c.tar.gz
gnupg-192113552faa98f40cc91fe014ec55861474626c.zip
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 <[email protected]>
-rw-r--r--scd/apdu.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/scd/apdu.c b/scd/apdu.c
index a42808c75..f00b35915 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -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;