scd: a race condition between scd_command_handler and handle_tick
Niibe Yutaka
gniibe at fsij.org
Wed Apr 4 03:43:55 CEST 2012
This is a bug report for GnuPG 2.0.19 (or 2.0.18). I have not yet
checked if there is this bug in the development version or not.
This bug was found at "make check" of building scute 1.4.0 for Debian.
I think that it is a bug of a race condition.
Here are failure logs:
https://buildd.debian.org/status/fetch.php?pkg=scute&arch=armel&ver=1.4.0-2&stamp=1333006067
https://buildd.debian.org/status/fetch.php?pkg=scute&arch=ia64&ver=1.4.0-3&stamp=1333361223
It surely occured on other non-exotic architectures. In fact, I
encountered on my amd64 box too (sorry, I lost the log).
NORMAL CASE:
Since the build environment doesn't have libpcsclite.so.1, pcsc daemon
wrappers fails at start up, and it results "Card error".
In the log, it's like:
-----------------------
gpg-agent[27706]: can't create directory `/home/buildd/.gnupg': No such file or directory
scdaemon[27707]: error sending PC/SC OPEN request: Broken pipe
gpg-agent[27706]: command learn failed: Card error
Skipping test because no token is present.
PASS: t-opensession
-----------------------
BUG CASE:
It seemed that opening PC/SC driver somehow succeeded wrongly after an
failure, and it tried to send APDUs to a reader which failed. In this
case, the error code is "Not supported", and it resulted failure of
scute's test.
In the log, it's like:
-----------------------
gpg-agent[27735]: can't create directory `/home/buildd/.gnupg': No such file or directory
scdaemon[27736]: error sending PC/SC OPEN request: Broken pipe
scdaemon[27736]: apdu_send_simple(0) failed: not supported
scdaemon[27736]: apdu_send_simple(0) failed: not supported
scdaemon[27736]: apdu_send_simple(0) failed: not supported
scdaemon[27736]: apdu_send_simple(0) failed: not supported
scdaemon[27736]: apdu_send_simple(0) failed: not supported
scdaemon[27736]: apdu_send_simple(0) failed: not supported
scdaemon[27736]: apdu_send_simple(0) failed: not supported
scdaemon[27736]: apdu_send_simple(0) failed: not supported
scdaemon[27736]: no supported card application found: Not supported
gpg-agent[27735]: command learn failed: Not supported
t-closeallsessions.c:48: Function failed
FAIL: t-closeallsessions
-----------------------
For NORMAL CASE, the function open_card failed correctly, as
apdu_connect failed because reader_table[slot].used == 0.
For the BUG CASE, there is a race condition between two threads, the
command handler thread and handle_tick thread.
COMMAND HANDLER THREAD's call-chain is like:
-> scd_command_handler
-> cmd_serialno
-> open_card
->apdu_connect
HANDLE_TICK THREAD's call-chain is like:
-> handle_tick
-> scd_update_reader_status_file
-> update_reader_status_file
-> get_reader_slot
-> apdu_open_reader
-> open_pcsc_reader
-> open_pcsc_reader_wrapper
-> new_reader_slot
Then, forking gnupg-pcsc-wrapper...
For the BUG CASE, it could be considered it goes like this:
HANDLE_TICK_THREAD COMMAND HANDLER THREAD
enter scd_command_handler
ctrl->reader_slot = 0
enter handle_tick
...
enter new_reader_slot
reader_table[slot].used = 1
forking gnupg-pcsc-wrapper and
thread switch occurs
enter cmd_serialno
enter open_card
enter apdu_connect
*** It succeeds, ***
*** as reader_table[slot].used == 1 ***
exit apdu_connect with success
failure of gnupg-pcsc-wrapper...
tries sending apdu...
I think that we need mutual exclusion between threads as
there is a shared resource (the connection to gnupg-pcsc-wrapper).
--
More information about the Gnupg-devel
mailing list