mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-18 14:17:03 +01:00
scd: Fix "Conflicting usage" bug.
* scd/apdu.c (apdu_close_reader): Call CLOSE_READER method even if we got an error from apdu_disconnect. * scd/app-common.h (no_reuse): Remove. * scd/app.c (application_notify_card_reset): Deallocate APP here. (select_application, release_application): Don't use NO_REUSE. -- Reproducible scenario: Invoke gpg --card-edit session from a terminal. Invoke another gpg --card-edit session from another. Remove a token. Insert a token again. Type RET on both terminals. One of terminal answers "Conflicting usage". Perhaps, having NO_REUSE field was to avoid race conditions. Now, APP can be safely deallocated by application_notify_card_reset. Thanks to the2nd. (backport of commit f42c50dbf00c2e6298ca6830cbe6d36805fa54a3)
This commit is contained in:
parent
01fa4c7b8b
commit
9934889415
@ -3136,7 +3136,13 @@ apdu_close_reader (int slot)
|
|||||||
return SW_HOST_NO_DRIVER;
|
return SW_HOST_NO_DRIVER;
|
||||||
sw = apdu_disconnect (slot);
|
sw = apdu_disconnect (slot);
|
||||||
if (sw)
|
if (sw)
|
||||||
return sw;
|
{
|
||||||
|
/*
|
||||||
|
* When the reader/token was removed it might come here.
|
||||||
|
* It should go through to call CLOSE_READER even if we got an error.
|
||||||
|
*/
|
||||||
|
log_debug ("apdu_close_reader => 0x%x (apdu_disconnect)\n", sw);
|
||||||
|
}
|
||||||
if (reader_table[slot].close_reader)
|
if (reader_table[slot].close_reader)
|
||||||
return reader_table[slot].close_reader (slot);
|
return reader_table[slot].close_reader (slot);
|
||||||
return SW_HOST_NOT_SUPPORTED;
|
return SW_HOST_NOT_SUPPORTED;
|
||||||
|
@ -44,11 +44,6 @@ struct app_ctx_s {
|
|||||||
operations the particular function pointer is set to NULL */
|
operations the particular function pointer is set to NULL */
|
||||||
unsigned int ref_count;
|
unsigned int ref_count;
|
||||||
|
|
||||||
/* Flag indicating that a reset has been done for that application
|
|
||||||
and that this context is merely lingering and just should not be
|
|
||||||
reused. */
|
|
||||||
int no_reuse;
|
|
||||||
|
|
||||||
/* Used reader slot. */
|
/* Used reader slot. */
|
||||||
int slot;
|
int slot;
|
||||||
|
|
||||||
|
27
scd/app.c
27
scd/app.c
@ -190,9 +190,12 @@ application_notify_card_reset (int slot)
|
|||||||
/* FIXME: We are ignoring any error value here. */
|
/* FIXME: We are ignoring any error value here. */
|
||||||
lock_reader (slot, NULL);
|
lock_reader (slot, NULL);
|
||||||
|
|
||||||
/* Mark application as non-reusable. */
|
/* Release the APP, as it's not reusable any more. */
|
||||||
if (lock_table[slot].app)
|
if (lock_table[slot].app)
|
||||||
lock_table[slot].app->no_reuse = 1;
|
{
|
||||||
|
deallocate_app (lock_table[slot].app);
|
||||||
|
lock_table[slot].app = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Deallocate a saved application for that slot, so that we won't
|
/* Deallocate a saved application for that slot, so that we won't
|
||||||
try to reuse it. If there is no saved application, set a flag so
|
try to reuse it. If there is no saved application, set a flag so
|
||||||
@ -265,16 +268,6 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app)
|
|||||||
return gpg_error (GPG_ERR_CONFLICT);
|
return gpg_error (GPG_ERR_CONFLICT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't use a non-reusable marked application. */
|
|
||||||
if (app && app->no_reuse)
|
|
||||||
{
|
|
||||||
unlock_reader (slot);
|
|
||||||
log_info ("lingering application `%s' in use by reader %d"
|
|
||||||
" - can't switch\n",
|
|
||||||
app->apptype? app->apptype:"?", slot);
|
|
||||||
return gpg_error (GPG_ERR_CONFLICT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we don't have an app, check whether we have a saved
|
/* If we don't have an app, check whether we have a saved
|
||||||
application for that slot. This is useful so that a card does
|
application for that slot. This is useful so that a card does
|
||||||
not get reset even if only one session is using the card - this
|
not get reset even if only one session is using the card - this
|
||||||
@ -506,15 +499,7 @@ release_application (app_t app)
|
|||||||
|
|
||||||
if (lock_table[slot].last_app)
|
if (lock_table[slot].last_app)
|
||||||
deallocate_app (lock_table[slot].last_app);
|
deallocate_app (lock_table[slot].last_app);
|
||||||
if (app->no_reuse)
|
lock_table[slot].last_app = lock_table[slot].app;
|
||||||
{
|
|
||||||
/* If we shall not re-use the application we can't save it for
|
|
||||||
later use. */
|
|
||||||
deallocate_app (app);
|
|
||||||
lock_table[slot].last_app = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lock_table[slot].last_app = lock_table[slot].app;
|
|
||||||
lock_table[slot].app = NULL;
|
lock_table[slot].app = NULL;
|
||||||
unlock_reader (slot);
|
unlock_reader (slot);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user