diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2024-11-18 06:25:58 +0100 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2024-11-18 06:25:58 +0100 |
commit | 261a08566e38faa49fd72b4440c4421622c57e06 (patch) | |
tree | 12e309138c447a171b758e09aa8835a998483da3 | |
parent | gpgconf: Include a minimal secure version in the --query-swdb output. (diff) | |
download | gnupg2-261a08566e38faa49fd72b4440c4421622c57e06.tar.xz gnupg2-261a08566e38faa49fd72b4440c4421622c57e06.zip |
scd: No hard lock-up when apdu_connect never returns.
* scd/app.c (new_card_lock): New.
(select_application): Scanning is serialized by NEW_CARD_LOCK.
For app_new_register, we hold the W-lock.
(initialize_module): Initialize NEW_CARD_LOCK.
--
GnuPG-bug-id: 7402
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r-- | scd/app.c | 19 |
1 files changed, 15 insertions, 4 deletions
@@ -63,6 +63,8 @@ struct mrsw_lock int notify_watchers; /* Used only for W32 but let's define it always. */ }; +static npth_mutex_t new_card_lock; + /* MRSW lock to protect the list of cards. * * This structure is used for serializing access to the list of cards @@ -940,8 +942,6 @@ select_application (ctrl_t ctrl, const char *name, gpg_error_t err = 0; card_t card, card_prev = NULL; - card_list_w_lock (); - ctrl->card_ctx = NULL; if (scan || !card_top) @@ -949,11 +949,12 @@ select_application (ctrl_t ctrl, const char *name, struct dev_list *l; int new_card = 0; + npth_mutex_lock (&new_card_lock); /* Scan the devices to find new device(s). */ err = apdu_dev_list_start (opt.reader_port, &l); if (err) { - card_list_w_unlock (); + npth_mutex_unlock (&new_card_lock); return err; } @@ -974,8 +975,10 @@ select_application (ctrl_t ctrl, const char *name, } else { + card_list_w_lock (); err = app_new_register (slot, ctrl, name, periodical_check_needed_this); + card_list_w_unlock (); new_card++; } @@ -987,12 +990,14 @@ select_application (ctrl_t ctrl, const char *name, } apdu_dev_list_finish (l); + npth_mutex_unlock (&new_card_lock); /* If new device(s), kick the scdaemon loop. */ if (new_card) scd_kick_the_loop (); } + card_list_w_lock (); for (card = card_top; card; card = card->next) { lock_card (card, ctrl); @@ -1039,7 +1044,6 @@ select_application (ctrl_t ctrl, const char *name, } else err = gpg_error (GPG_ERR_ENODEV); - card_list_w_unlock (); return err; @@ -2633,6 +2637,13 @@ initialize_module_command (void) int ret; #endif + if (npth_mutex_init (&new_card_lock, NULL)) + { + err = gpg_error_from_syserror (); + log_error ("app: error initializing mutex: %s\n", gpg_strerror (err)); + return err; + } + card_list_lock.num_readers_active = 0; card_list_lock.num_writers_waiting = 0; card_list_lock.writer_active = 0; |