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:
parent
17b766b0a3
commit
261a08566e
19
scd/app.c
19
scd/app.c
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user