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
Clear outputs in PKCS12_parse error handling #4145
Conversation
This calls for kind of "philosophical" question. Is it appropriate to modify any of **arguments if you end up returning error? Maybe it would be more appropriate to keep results in local variables till you know that you'll be returning success and only then pass them back through corresponding *arguments? On the other hand if zeroing *arguments is deemed appropriate, then perhaps it would be worth mentioning in "RETURN VALUES" paragraph? Comment applies even to #4146. |
Don't know. For me it is more a practical problem, how to write a correct application. The problem is that ca is an in-out and whatever is there on return needs But pkey and cert need not even be initialized to zero before the call.
I expect that mostly all programs will look like that:
And that's what I would like to fix. |
I'd say that it would rather be
But the original question is rather about formal style. You can view it like this. Which of the two would make auditor's life easier. Not necessarily human's, one can as well wonder how would it affect resource consumption of some kind of static code analyzer... |
Update to .pod means that you might have to split request even between 1.1.0 and master. As alternative it might be appropriate to say that code modifications apply to both, but .pod update, only to master. And if deemed appropriate, .pod update |
Yes, I'd expect the code change can be cherry picked to 1.1.0 and the .pod update is master only. |
In your code example there is a potential memory leak in *ca, which is not and has never Returning *ca in exactly the same state as it was before the call could be challenging. |
Maybe, but it has lesser to do with the original point:-) Suggested modification is fine for current semantic, but my question if we need to change the latter. My suggestion to wait a little bit for others to speak up... |
I'm adding "pending 2nd review" to denote the fact that additional opinion is requested. Question is what is more appropriate. To modify output arguments even if en error is returned (as currently). Or to modify the code so that in case of error output arguments are never modified. |
I'd go for the don't change any of the output arguments on error option. For |
From a pragmatic point of view the normal style I would follow is that you clear your output arguments (if they are pointers to pointers set them to NULL) so that they are "valid" on return whether there is an error or not. Guaranteeing not to change output arguments on error is something I would absolutely not do - as there are a large range of code paths in general and either it is okay to start changing values or you should never change values. The half-way-in-between doesn't help anyone. |
Definitely. |
As an additional data point, IIUC in krb5 style we would do something like this pseudocode:
which uses more memory but is easier to reason about. |
That's a much easier way to handle I think it is the input/output I'm kind of tempted to add a reserve n new slots to the stack data type -- pretty much all the code for this is present already. |
I would expect that keeping whatever is in pkey and cert before the call can easily break All I want to change here is a corner-case that is hard to reach without either a out-of-memory I agree that keeping ca in exactly the same state as before the call might be an improvement. |
@paulidale: I already write this code to pre-allocate stack ; it is staging in my repo. I can PR it ? |
It would be utterly irresponsible of them to make such assumption in case an error is returned. Besides, suggested fix actually speaks against this argument. Because as it is now it frees *pkey, but doesn't nullifies it, effectively exposing caller that wouldn't pay attention to double-free. According to your reasoning that is. Or in other words if there were applications that didn't pay attention to return code, then we would probably know about it. Well, if you examine call to PKCS12_parse in apps/apps.c you might get an impression that suggested nullifying would be appropriate. But at the same time not touching arguments would work (and I'd still argue that it's more appropriate), because caller is explicit about nullifying before call. "Vote count" appears to be 2 vs. 3 in favour of don't touch in case of error, or did I count wrong? |
Sorry I can't agree with that. It should be extremely difficult to reach that code path where *pkey |
By the way, when I look at apps/apps.c, there is one call that will probably never work:
That is because PKCS12_parse will never populate *cert if pkey is NULL. |
Does it matter in the context? I mean formally speaking it is still a possibility... Well, you can argue that not nullifying was a bug and it's OK for application to disregard return code and instead rely on values *pkey and *cert being NULL. Note however that manual page reads "if successful the private key will be written to *pkey, ..." |
Sure, it would be appropriate. Directly here or elsewhere... |
I think I have lost rack of what the next step is, here. (I would not mind if the current diff gets applied as an interim step; it seems a clear improvement over the current master.) |
I've no objection, but it might be worthwhile waiting to see the answer to the erase or don't touch question. |
I reckon that majority of involved is in favour of not touching output arguments in case of error. One can argue that it would be sensible to commit this and address not-touching in another request, but then somebody has to keep track. One can put a note in form of issue, but in such case I would suggest to abstain from modifying corresponding .pod file in this request. |
Yes. I agree. Especially for master, this sounds reasonable. |
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.
1st commit only
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.
like andy said
Reviewed-by: Andy Polyakov <appro@openssl.org> Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from #4145)
Pushed first commit to master and 1.1.0, thanks! |
Reviewed-by: Andy Polyakov <appro@openssl.org> Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from openssl#4145) (cherry picked from commit 524fdd5)
The function PKCS12_parse may return invalid pointers in *pkey and *cert
in case of an error.
This ensures that the returned values are always zero if anything happens.