scd: call update_card_removed only when detecting removal

NIIBE Yutaka gniibe at
Mon Mar 25 05:33:11 CET 2013

This is a change to SCDaemon to avoid unnecessary "learn" after card

When we do:

  (1) insert card
  (2) run "gpg2 --card-status"
  (3) remove card
  (4) invoke "gpg2 --card-edit"
  (5) invoke some command like "verify"

The step #5 fails (but with no message to user, this is another bug).

This is because the function update_reader_status_file calls
update_card_removed after the card is available.  The thread of
scd_update_reader_status_file, after "gpg2 --card-edit" was done by
user, does not need to call the function, or rather, should not call
the function.

It the past, it should call the function (only) when the thread itself
does do_reset for the card to let the application invoke "learn".

In the past, the thread of scd_update_reader_status_file polls (at the
period of 0.5 second) to detect card availability, so it is mostly
this thread which calls do_reset.  I think that this is the reason why
this bug hasn't been caught.  Still, this is a bug, because there is a
race condition between the thread and an application thread.

Now, the thread of scd_update_reader_status_file only polls for active
card/token, and it is always an application thread which calls
do_reset, any commands will fail.

Built and tested for STABLE-BRANCH-2-0.  Will do that for master, too.

diff --git a/scd/command.c b/scd/command.c
index e45153f..fc1f5a2 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -2310,10 +2310,8 @@ update_reader_status_file (int set_card_removed_flag)
             xfree (homestr);
-          /* Set the card removed flag for all current sessions.  We
-             will set this on any card change because a reset or
-             SERIALNO request must be done in any case.  */
-          if (ss->any && set_card_removed_flag)
+          /* Set the card removed flag for all current sessions.  */
+          if (ss->any && ss->status == 0 && set_card_removed_flag)
             update_card_removed (idx, 1);
           ss->any = 1;

More information about the Gnupg-devel mailing list