1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

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>
This commit is contained in:
NIIBE Yutaka 2024-11-18 14:25:58 +09:00
parent 17b766b0a3
commit 261a08566e
No known key found for this signature in database
GPG Key ID: 640114AF89DE6054

View File

@ -63,6 +63,8 @@ struct mrsw_lock
int notify_watchers; /* Used only for W32 but let's define it always. */ 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. /* MRSW lock to protect the list of cards.
* *
* This structure is used for serializing access to 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; gpg_error_t err = 0;
card_t card, card_prev = NULL; card_t card, card_prev = NULL;
card_list_w_lock ();
ctrl->card_ctx = NULL; ctrl->card_ctx = NULL;
if (scan || !card_top) if (scan || !card_top)
@ -949,11 +949,12 @@ select_application (ctrl_t ctrl, const char *name,
struct dev_list *l; struct dev_list *l;
int new_card = 0; int new_card = 0;
npth_mutex_lock (&new_card_lock);
/* Scan the devices to find new device(s). */ /* Scan the devices to find new device(s). */
err = apdu_dev_list_start (opt.reader_port, &l); err = apdu_dev_list_start (opt.reader_port, &l);
if (err) if (err)
{ {
card_list_w_unlock (); npth_mutex_unlock (&new_card_lock);
return err; return err;
} }
@ -974,8 +975,10 @@ select_application (ctrl_t ctrl, const char *name,
} }
else else
{ {
card_list_w_lock ();
err = app_new_register (slot, ctrl, name, err = app_new_register (slot, ctrl, name,
periodical_check_needed_this); periodical_check_needed_this);
card_list_w_unlock ();
new_card++; new_card++;
} }
@ -987,12 +990,14 @@ select_application (ctrl_t ctrl, const char *name,
} }
apdu_dev_list_finish (l); apdu_dev_list_finish (l);
npth_mutex_unlock (&new_card_lock);
/* If new device(s), kick the scdaemon loop. */ /* If new device(s), kick the scdaemon loop. */
if (new_card) if (new_card)
scd_kick_the_loop (); scd_kick_the_loop ();
} }
card_list_w_lock ();
for (card = card_top; card; card = card->next) for (card = card_top; card; card = card->next)
{ {
lock_card (card, ctrl); lock_card (card, ctrl);
@ -1039,7 +1044,6 @@ select_application (ctrl_t ctrl, const char *name,
} }
else else
err = gpg_error (GPG_ERR_ENODEV); err = gpg_error (GPG_ERR_ENODEV);
card_list_w_unlock (); card_list_w_unlock ();
return err; return err;
@ -2633,6 +2637,13 @@ initialize_module_command (void)
int ret; int ret;
#endif #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_readers_active = 0;
card_list_lock.num_writers_waiting = 0; card_list_lock.num_writers_waiting = 0;
card_list_lock.writer_active = 0; card_list_lock.writer_active = 0;