-
Notifications
You must be signed in to change notification settings - Fork 160
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
undefined behavior in gcc-compatible detected by ubsan #327
Comments
The code is voluntarily not defensive, there is a precondition that is that you should not be passing a null pointer to that function. I think this should be better documented though. |
i wasnt even are there is documentation for the C api. could you point me to it? |
@beurdouche I took a look and I couldn't see the non-null precondition here: did you find it somewhere? https://github.com/project-everest/hacl-star/blob/master/code/chacha20poly1305/Hacl.Impl.Chacha20Poly1305.fst#L151 I should have given an update on this: we took a long hard look at this issue back when you reported it, and actually found there is an issue: our model of C, Low*, allows the user to successfully perform Alas, this occurs everywhere an input may have length 0: it is idiomatic, even reasonable, for C callers to pass NULL when they want to have, say, no additional authenticated data. And it is not reasonable to ask C callers to heap-allocate a dummy just to call our functions. (Note: zero-length stack allocations are UB, so callers can't even do that as a dummy for the aad.) Writing a defensive API would amount to checking whether aad has length zero, heap-allocating a dummy, calling the HACL functions, freeing the dummy, returning the result. This is clearly too much. The "right" solution is to fix Low* and then fix HACL*. I had attempted to automate the Low* fix as much as I could on branch I think there's still the hashes that ought to be fixed, and perhaps a couple more algorithms. In the grand scheme of things, even though all UBs are bad, this one might be on the milder side. But still needs fixing, of course. @beurdouche if you have cycles, getting Marina's branch up to speed and assessing what remains to be done would be quite high-impact. I think we were quite close, but unfortunately we all got distracted with other things. Thanks, Jonathan |
thanks for the detailed response. i'd agree that it is idiomatic C to pass NULL for empty strings. But i'm not sure if this specific api needs to be defensive. C is full of pitfalls like this, so anyone using it already knows to check the comments above a function or the manual. Adding a warning to the manual is fine. Ideally of course, the function would be able to accept null and just do nothing. I guess that's what you said with the ongoing effort. Sounds great! |
I agree that adding a disclaimer for now pointing to this issue would be good. Apologies once again for not responding: I was leading a big effort to try to make this happen, and I was hoping to just respond "it's fixed", but unfortunately it didn't work out as expected. Internally, what typically happens is that there's something along the lines of (pseudo-code):
the second to last line is what triggers the UB. That's because our code is too generic, and now we need to add fast-paths everywhere for when the input length is zero, which is actually more work. @polubelova probably remembers a little bit of this and perhaps give an update on what was mostly fixed and what could still use some work... |
I found a copy of the message I had written on Slack -- apparently I had saved it somewhere knowing it would eventually disappear. I'm pasting a copy for reference to make sure we have everything in this discussion. Some soundness issues related to the treatment and modeling of the NULLpointer in Low*. Background context.We model the NULL pointer as an always-live buffer of size 0. I realize Consequence: since NULL will inevitably be passed around for any array
This means that the notion of valid pointer in Low* must encompass the The issue.Short version: having the NULL pointer wandering around your code causes What came out as a surprise today (bug report: What was previously known is that (see Since KreMLin generates C code that performs pointer addition, and uses Proposed solution (Low*).In branch To avoid breaking clients, Proposed solution (clients, e.g. HACL*)Naturally, this is going to generate quite a few ugly code-gen changes. What I suggest is to extend Lib.Buffer in HACL with a similar strategy. The same thing can be done for other operations. Individual algorithms can be fixed by either switching to
Thanks to @beurdouche, @R1kM for insightful discussions, and to |
Note, that because passing a null aad is quite frequent, I protected the call in #413 so that if the length is zero you won't have to pass a non-null pointer anymore. As Jonathan mentioned above, we are considering more global solutions to avoid the users to be confused by these issues. |
Yes, hashes are effected as well. I'll leave it to @msprotz whether this should get a hotfix as well. |
Yeah, I guess a hotfix for hashes would be good, too, actually. Do you have an exhaustive list of all the places where this specific UB happens? |
Unfortunately not. Any place that might get a null pointer as input and tries to do something with it 😉 |
ubsan is unhappy about a bunch of things. i'm unsure if these are due to incorrect usage? The C output is a bit difficult to read.
The text was updated successfully, but these errors were encountered: