-
Notifications
You must be signed in to change notification settings - Fork 711
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Card driver should return SC_ERROR_INVALID_CARD on failures during initialisation #946
Comments
I think it would be easiest if you propose a patch. I'm pretty sure that |
In sc_connect_card, the reusing of the card structure after a card driver returns SC_ERROR_INVALID_CARD assumes that the card driver has cleaned up anything it did in its *_init routine. Above I said:
It is now 4 card drivers return SC_ERROR_INVALID_CARD:
All the drivers above do a match_atr for their own cards first. So the select AID is only done for those ATRs. The only issue could be if other drivers can also match on those ATRs. card-dnie.c does not cause any problems, but could be simplified to not match that ATR or return no match for that ATR. So one could call this a card-driver problem for now and ask @viktorTarasov to look at card-oberthur.c and @martinpaljak to look at card-mrcd.c But new card drivers must make sure they clean up the card structure before returning SC_ERROR_INVALID_CARD from their *-init routines. @frankmorgner You can leave this open as enhancement or call it a problem with 2 drivers or just close it. |
Issue: #943 The underlying issue was card/reader/pcsc was returning 90 00 when selecting AID which does not exist on the card. This appears to be some configuration issue and not a bug in the card driver. But the problem did uncover some other issues with how a failure in init is handled.
sc_connect_card() in card.c will call ops->match_card(card). If true is returned ops->init(card) will be called. If SC_ERROR_INVALID_CARD is returned, the loop will be continued. If not the loop will end.
One problem is card drivers expect if ops->init(card) is called then ops->finish(card) will be called to clean up. This is not done in the loop. This can cause memory leaks.
I would like to propose:
Evaluate the error codes in each driver to see if it should return SC_ERROR_INVALID_CARD indicating that the driver thinks that other drivers (if any) should be tried, or it is some other failure and no other drivers should be tried. (Maybe this should be in the loop?)
In the loop, if ops->init(card) returns SC_ERROR_INVALID_CARD, ops->finish(card) is called. and card->dvr_data = NULL;
Evaluate each driver to see if it depends on any fields in card that may have been changed by a previous card driver's init routine, and make sure these are reset if we continue the loop. We have done this already for many cases.
We have 37 card drivers (and iso7816.c)
ls card-*.c | wc
27 drivers define a *_finish routine:
grep "_finish(.*sc_card.*)" card-*.c
(card-openpgp.c is counted twice in the above grep).
28 drivers set the ops.finish:
grep "ops[.]finish.*=" card-*.c
10 drivers do not set ops.finish and use what iso7816.c which is a NULL pointer.
grep -L "ops[.]finish.*=" card-*.c
8 of these do not reference drv_data. The other 2 set drv_data = NULL.
grep -L "drv_data" card-*.c
3 cards may return SC_ERROR_INVALID_CARD to try and continue the loop:
grep SC_ERROR_INVALID_CARD card-*.c
Only card-openpgp.c in pgp_init does a cleanup by calling its own pgp_finish(card)
Also see #945 that only addressed one driver.
The text was updated successfully, but these errors were encountered: