diff options
author | Werner Koch <[email protected]> | 2021-09-07 14:40:09 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2021-09-07 14:40:09 +0000 |
commit | 192113552faa98f40cc91fe014ec55861474626c (patch) | |
tree | ca3908b8535bcc14fbfeabb16de3c019d54377b0 | |
parent | agent: Fix segv in GET_PASSPHRASE (regression) (diff) | |
download | gnupg-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.c | 18 |
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; |