summaryrefslogtreecommitdiffstats
path: root/scd
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2024-11-18 06:25:58 +0100
committerNIIBE Yutaka <gniibe@fsij.org>2024-11-18 06:25:58 +0100
commit261a08566e38faa49fd72b4440c4421622c57e06 (patch)
tree12e309138c447a171b758e09aa8835a998483da3 /scd
parentgpgconf: Include a minimal secure version in the --query-swdb output. (diff)
downloadgnupg2-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>
Diffstat (limited to 'scd')
-rw-r--r--scd/app.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/scd/app.c b/scd/app.c
index d09b931e6..ba7bb23e1 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -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;