mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
scd: Fix RESET command handling (more).
* scd/app-common.h (struct app_ctx_s): Add reset_requested. * scd/app.c (app_reset): Locking APP, set reset_requested. (deallocate_app): Release the lock. (release_application): Add LOCKED_ALREADY argument. (scd_update_reader_status_file): Hold the lock when accessing APP. When reset_requested is set, close the reader and deallocate APP. * scd/command.c (open_card_with_request, cmd_restart): Follow the change of release_application. (send_client_notifications): Here it calls release_application holding the lock. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
7006352da7
commit
99d4dfe836
@ -54,6 +54,7 @@ struct app_ctx_s {
|
||||
const char *apptype;
|
||||
unsigned int card_version;
|
||||
unsigned int card_status;
|
||||
unsigned int reset_requested:1;
|
||||
unsigned int periodical_check_needed:1;
|
||||
unsigned int did_chv1:1;
|
||||
unsigned int force_chv1:1; /* True if the card does not cache CHV1. */
|
||||
@ -132,7 +133,7 @@ gpg_error_t select_application (ctrl_t ctrl, const char *name, app_t *r_app,
|
||||
int scan, const unsigned char *serialno_bin,
|
||||
size_t serialno_bin_len);
|
||||
char *get_supported_applications (void);
|
||||
void release_application (app_t app);
|
||||
void release_application (app_t app, int locked_already);
|
||||
gpg_error_t app_munge_serialno (app_t app);
|
||||
gpg_error_t app_write_learn_status (app_t app, ctrl_t ctrl,
|
||||
unsigned int flags);
|
||||
|
29
scd/app.c
29
scd/app.c
@ -143,19 +143,23 @@ app_reset (app_t app, ctrl_t ctrl, int send_reset)
|
||||
|
||||
if (send_reset)
|
||||
{
|
||||
int sw = apdu_reset (app->slot);
|
||||
int sw;
|
||||
|
||||
lock_app (app, ctrl);
|
||||
sw = apdu_reset (app->slot);
|
||||
if (sw)
|
||||
err = gpg_error (GPG_ERR_CARD_RESET);
|
||||
|
||||
/* Release the same application which is used by all sessions. */
|
||||
send_client_notifications (app, 1);
|
||||
app->reset_requested = 1;
|
||||
unlock_app (app);
|
||||
|
||||
scd_kick_the_loop ();
|
||||
gnupg_sleep (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctrl->app_ctx = NULL;
|
||||
release_application (app);
|
||||
release_application (app, 0);
|
||||
}
|
||||
|
||||
return err;
|
||||
@ -454,6 +458,8 @@ deallocate_app (app_t app)
|
||||
}
|
||||
|
||||
xfree (app->serialno);
|
||||
|
||||
unlock_app (app);
|
||||
xfree (app);
|
||||
}
|
||||
|
||||
@ -463,7 +469,7 @@ deallocate_app (app_t app)
|
||||
actually deferring the deallocation to allow for a later reuse by
|
||||
a new connection. */
|
||||
void
|
||||
release_application (app_t app)
|
||||
release_application (app_t app, int locked_already)
|
||||
{
|
||||
if (!app)
|
||||
return;
|
||||
@ -473,12 +479,15 @@ release_application (app_t app)
|
||||
is using the card - this way the PIN cache and other cached data
|
||||
are preserved. */
|
||||
|
||||
lock_app (app, NULL);
|
||||
if (!locked_already)
|
||||
lock_app (app, NULL);
|
||||
|
||||
if (!app->ref_count)
|
||||
log_bug ("trying to release an already released context\n");
|
||||
|
||||
--app->ref_count;
|
||||
unlock_app (app);
|
||||
if (!locked_already)
|
||||
unlock_app (app);
|
||||
}
|
||||
|
||||
|
||||
@ -1019,9 +1028,10 @@ scd_update_reader_status_file (void)
|
||||
int sw;
|
||||
unsigned int status;
|
||||
|
||||
lock_app (a, NULL);
|
||||
app_next = a->next;
|
||||
|
||||
if (a->ref_count == 0)
|
||||
if (a->reset_requested)
|
||||
status = 0;
|
||||
else
|
||||
{
|
||||
@ -1036,6 +1046,7 @@ scd_update_reader_status_file (void)
|
||||
/* Get status failed. Ignore that. */
|
||||
if (a->periodical_check_needed)
|
||||
periodical_check_needed = 1;
|
||||
unlock_app (a);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -1056,12 +1067,14 @@ scd_update_reader_status_file (void)
|
||||
a->card_status = status;
|
||||
if (a->periodical_check_needed)
|
||||
periodical_check_needed = 1;
|
||||
unlock_app (a);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a->periodical_check_needed)
|
||||
periodical_check_needed = 1;
|
||||
unlock_app (a);
|
||||
}
|
||||
}
|
||||
npth_mutex_unlock (&app_list_lock);
|
||||
|
@ -227,7 +227,7 @@ open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
|
||||
|
||||
/* Re-scan USB devices. Release APP, before the scan. */
|
||||
ctrl->app_ctx = NULL;
|
||||
release_application (app);
|
||||
release_application (app, 0);
|
||||
|
||||
if (serialno)
|
||||
serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
|
||||
@ -1495,7 +1495,7 @@ cmd_restart (assuan_context_t ctx, char *line)
|
||||
if (app)
|
||||
{
|
||||
ctrl->app_ctx = NULL;
|
||||
release_application (app);
|
||||
release_application (app, 0);
|
||||
}
|
||||
if (locked_session && ctrl->server_local == locked_session)
|
||||
{
|
||||
@ -1922,7 +1922,7 @@ send_client_notifications (app_t app, int removal)
|
||||
{
|
||||
sl->ctrl_backlink->app_ctx = NULL;
|
||||
sl->card_removed = 1;
|
||||
release_application (app);
|
||||
release_application (app, 1);
|
||||
}
|
||||
|
||||
if (!sl->event_signal || !sl->assuan_ctx)
|
||||
|
Loading…
x
Reference in New Issue
Block a user