-
Notifications
You must be signed in to change notification settings - Fork 10
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 panics on failed initialization #165
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #165 +/- ##
==========================================
- Coverage 90.74% 90.73% -0.01%
==========================================
Files 31 31
Lines 6158 6436 +278
==========================================
+ Hits 5588 5840 +252
- Misses 570 596 +26 ☔ View full report in Codecov by Sentry. |
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 think this is a step in the right direction, but I would prefer to combine this with a general improvement of the initialization steps:
Generally, we can expect that all other calls are wrapped in a pair of C_Initialize
/C_Finalize
calls. (Except for C_GetFunctionList
, which can be called at any time.)
As far as I see, this implementation would still allow other calls without C_Initialize
, and initialization errors would cause an unclear general error. On the other hand, C_GetFunctionList
would unnecessarily fail if there is a problem with the configuration. Also, it is easy to miss an ensure_init()
call, then access DEVICE
and still cause a panic.
My suggestion would be to only initialize the device in C_Initialize
and return CKR_FUNCTION_FAILED
if it fails. All other calls should check if initialization has been performed (and not finalized) and return CKR_CRYPTOKI_NOT_INITIALIZED
instead. Accessing DEVICE
directly should not panic in the error case, but also return CKR_CRYPTOKI_NOT_INITIALIZED
. C_Finalize
should reset the device.
This would lead to better error messages, consistent behavior if a C_Initialize
call is missing, and it would reduce the chance of programming errors when accessing DEVICE
.
What do you think?
3ba757e
to
7c166ad
Compare
I would like to change the approach so that the statics are only used in the top level calls, and every thing else takes a But so that I correctly understand your approach, you would make the That could work but I'm not sure how much it would work in a multithreaded context. I'd need to learn how PKCS11 deals with that. Given the weird nginx workarournds and #157 I think this can be approached in another PR. Maybe in this one I can remove the |
An alternative approach would be to use I’m fine with splitting this up into a separate PR, but I’d still like to change the error codes and the direct
That would mean that calls after |
Ok, I will do that then, but I think some uses of |
Thanks! In that case, having an explicit panic is IMHO still preferable to an indirect panic through accessing a lazy static. |
a1b35c7
to
db98e5e
Compare
Done, the non-tested lines are all error handling that should never happen. |
Can you confirm that this still works with forks, that is, if the process that dlopened this module forks and then calls C_Initialize? (for example the tokio runtime can't handle that, see tokio-rs/tokio#1541, so there are dragons luring). One of the issues is: you can't cleanly fork if there are threads created already. |
Do you have an example test for that from the previous errors you and Nils encountered? It would be nice to have it in CI because that would be broken easily on accident. This will be especially relevant as I plan on tackling #157 next. |
I don't think anything I've done in this PR should change how it interacts with |
Ok, maybe this is not relevant because I mix it up with the LazyStatic that is mentioned in issue #163. I just wanted to throw it in, in case it's related. The only example I have is running an actual nginx, that's where we saw the issues. I'm not aware of a test, that @nponsard wrote for that, but would certainly be useful. It would require loading the module with dlopen(), then doing a fork, and then testing the functionality of the module in the fork. |
I did not write any test for that, when I was investigatig the forking issue I was running the nginx example. |
Just tested on top of the images in #169 , it works with nginx. Now testing with apache. |
Both work, with a slight need for an update of the apache image which is incorrect in #169 |
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.
LGTM, thanks!
This patch adds a `Result` version of the `Device` static so that any call can first check that the initialization was successful.
This removes panic paths in the initialization of the device.
return CKR_CRYPTOKI_NOT_INITIALIZED in other calls when not initialized
4157673
to
ff07b5e
Compare
This patch
Result
version of theDevice
static so that any call can first check that the initialization was successfuladd_parseable_certificates
to discard unparseable certificates rather than panic. If no certificate is parsed, the initialization returns an error.fix #161