-
Notifications
You must be signed in to change notification settings - Fork 803
Fix record based files #2511
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
Fix record based files #2511
Conversation
|
Ups, I have accidentally added some files that were not in .gitignore. What is best practice to remove them from the pull request? |
|
Just add a commit with a fixup on-top. if needed, you can cleanup later. |
|
force-push is OK, too |
|
your changes look a bit rough. please check whether you can split this into multiple commits that are easier to review. Also, you've added comments to the source code regarding the actual change, which instead belongs into the commit message. |
2aff95d to
abcb194
Compare
|
I have reduced the changes to the known issues and split them into 2 commits. Hope that's better. For the other issues I create appropriate tickets. |
|
Fuzzing failed. I checked the logs but can't see a relation to the changes. @frankmorgner could you please have a look? Thanks. |
|
The CIFuzz failed, because some driver tried to allocate some insane memory size, probably because of some change in your code: I can reproduce it in your branch with: This needs to be fixed before we will merge this change. Allocating 4GB of memory for some bugus file that might be on a smart card is wrong. There needs to be some limits. We usually use |
|
The debug log looks like this if you run with so the problem is in the new handling of |
|
Well, strictly speaking |
…ed fuzzing. Also limit record and file size in sc_pkcs15_read_file(). Change result code for record out of bounds.
|
AppVeyor build failed with temporary error. Rerun? |
src/libopensc/iso7816.c
Outdated
| size <<= 8; | ||
| size |= (uint32_t) p[i]; | ||
| } | ||
| file->size = (size > MAX_FILE_SIZE)? MAX_FILE_SIZE:size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather print some debug message if we go over the size (and maybe fail) than just max it on this value.
It is very unlikely that this will happen with real cards, but if it does, verbose log message is great help for debugging.
Also please, keep whitespaces around operators, if, for and similar as in the rest of the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current approach is to check for MAX_FILE_SIZE when the actual allocation is done... Capping this here, is certainly useful, but a debug message would be good.
src/libopensc/pkcs15.c
Outdated
| if(file->record_length > 0) { | ||
| len = (file->record_length > MAX_FILE_SIZE)? MAX_FILE_SIZE:file->record_length + 5; | ||
| } else { | ||
| len = 0x2000 + 5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this magic constant coming from somewhere specific or is it just arbitrary number? In any case, it should have some comment in the code so the people reading the code in couple of years do not have to ask the same question.
src/libopensc/pkcs15.c
Outdated
|
|
||
| apdu.data = offset_buffer; | ||
| apdu.datalen = 4; | ||
| apdu.lc = 4; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe sizeof(offset_buffer) would be more readable, but this is probably about personal taste
| if (r < 0) goto fail_unlock; | ||
|
|
||
| if(data_do) { | ||
| memcpy(data + offset_u16, data_do, data_do_len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume you can do this because you added +5 to the data allocated above.
I would consider reading the data into buffer of SC_MAX_APDU_RESP_SIZE size, do the decoding in there and only after that copy the result to the data buffer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I think is more important, @wcosnc correctly identified that sc_read_record (or its counterpart read_record in the card driver call backs) doesn't allow specifying an offset. Doing this here, is bad since we want to have the flexibility of implementing this depending on the card driver in use.
Currently, only iso7816.c has an implementation of read_record so changing this would have very minimal impact on the other cards. I suggest you do the following:
- add an additional parameter to both sc_read_record and read_record, named idx (just like in sc_read_binary)
- Use idx = 0 where sc_read_record is currently called without this parameter
- change read_record in iso7816.c so that if and only if
idx != 0your implementation is used with INS=B3. if idx is not specified (i.e. 0), then it should still use the current version with INS=B2 - use the new sc_read_record to specify the offset in sc_pkcs15_read_file
Co-authored-by: Jakub Jelen <[email protected]>
|
@wcosnc did you have time to get back to the comments? |
|
I haven't found the time yet. I'm going to edit the code the next days. |
|
@frankmorgner Could you please have a look at the tests? I can't see a direct relation to the code. Thank you. |
frankmorgner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed the parsing a little bit. (I wanted to make a "suggestion" for a change, but Github pushed the change onto your pull requests, I hope that is OK)
Allowing specification of an offset in sc_read_file is a generic change, that should be fixed properly. Your changes are technically good, but they belong into the lower level of the card abstraction, I think.
| if (r < 0) goto fail_unlock; | ||
|
|
||
| if(data_do) { | ||
| memcpy(data + offset_u16, data_do, data_do_len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I think is more important, @wcosnc correctly identified that sc_read_record (or its counterpart read_record in the card driver call backs) doesn't allow specifying an offset. Doing this here, is bad since we want to have the flexibility of implementing this depending on the card driver in use.
Currently, only iso7816.c has an implementation of read_record so changing this would have very minimal impact on the other cards. I suggest you do the following:
- add an additional parameter to both sc_read_record and read_record, named idx (just like in sc_read_binary)
- Use idx = 0 where sc_read_record is currently called without this parameter
- change read_record in iso7816.c so that if and only if
idx != 0your implementation is used with INS=B3. if idx is not specified (i.e. 0), then it should still use the current version with INS=B2 - use the new sc_read_record to specify the offset in sc_pkcs15_read_file
|
@wcosnc @frankmorgner what is the status of this PR? Do we want to consider it for 0.23.0? We need at least to resolve conflicts. |
|
closing this as #2604 is merged |
Fixes #2504 and #2505.