-
Notifications
You must be signed in to change notification settings - Fork 273
Memory primitives in assume
are unchecked
#5955
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
Comments
A simpler example: #include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
void main()
{
char *data;
data = malloc(1);
__CPROVER_assume(__CPROVER_r_ok(data, 128));
assert(__CPROVER_r_ok(data, 128));
} No warnings / errors and verification succeeds with the following cmdline:
Full output from CBMC
|
assume
assume
are unchecked
I've done some exploration of this issue and there are two different things interacting that cause the unexpected behaviour. One appears to be a misunderstanding about how Part 1 - Misunderstanding CBMCTo explain the misunderstanding let's consider the simpler example:
Now there are several commands we can run to show interesting output (somewhat simplified from the above). Let's use the following to illustrate:
which produces the following output (I've added cat for illustration):
The key point here is that the assertion on line 12 passes. This appears to be sufficient to illustrate the misunderstanding with
Observe that here the assertion on line 13 does not fail. This is because of how To understand this, let us consider the
The internals of
Note that line 12 can be commented out and line 13 will still succeed. To conclude the misunderstanding part, since the path becomes unreachable any checks are considered to succeed by Part 2 - Different smt2 BehaviourThe second aspect of this issue is that there is different behaviour when the Some experiments show that the smt2 outfile for the examples does indded include
but I have not checked if the details sent to Z3 are different to the outfile. That said, the path to addressing them has the same question: is this an urgent bug to explore and fix considering the upcoming work on rewriting the SMT backend? |
Thanks for looking into this, @TGWDB. Regarding part 1, we understand that that incorrect use of Regarding part 2, no fixing the SMT issue with the old backend is not urgent. It probably is the same issue as #5952, as you mentioned, and that's on my todo list, but it's not urgent. |
Selectively quoting:
I'm not quite following why the example is a case of unintuitive semantics -- it seems Isn't it really coverage checking that you need? |
But
That's one approach yes ... but we don't yet have an automated coverage check. I also think it might be hard to enforce such an automated check because the acceptable coverage across harnesses varies a lot -- may be @feliperodri can comment. |
@tautschnig not only for coverage checking, but also to check for valid pointers. |
Unless coverage checking is enabled, there never is information about unreachable checks. That's why coverage checking is (at least: currently) necessary. As much as I do agree that the memory primitives have their surprising pitfalls: I'm not sure why they'd deserve preferential treatment here. The example that @SaswatPadhi posted at the beginning of this conversation is a really good case here: one can easily construct arbitrarily complex assumptions, and, yes, some of them will result in vacuous proofs. Some of them might contain memory primitives, but that's not at all a necessary condition. From my point of view, there are two possible routes forward. Further suggestions would be much appreciated!
|
They could be very useful when dealing with pointers and we often tried to use them, but fell in their pitfalls. So, targeting them here wouldn't solve the vacuity problem, but it'd at least help users to not apply them in the wrong context unintentionally.
I think this is unnecessary for now, because we already perform coverage checking in proof harnesses.
I like this idea. This would make clear to proof writers "be aware where you're using these primitives". @SaswatPadhi @mww-aws @markrtuttle any thoughts? |
+1. I like it too. This is exactly what I was trying to say when I mentioned that we should warn users about using these primitives in |
Sure, I am closing this issue. A fix for #6057 would also check for vacuity due to usage of memory primitives in assume context. |
Uh oh!
There was an error while loading. Please reload this page.
CBMC version:
develop
Operating system: Mac OS 10.15.7
I know it's recommended not to use
__CPROVER_r_ok
within__CPROVER_assume
, but it's not enforced -- no error from CBMC.Some projects (e.g. throughout s2n) use this, and the point of this test case is to demonstrate that CBMC would accept bad programs when
__CPROVER_r_ok
is used in__CPROVER_assume
, and give a false guarantee of correctness even with all of the pointer-checking flags enabled.Test case:
Exact command line resulting in the issue:
What behaviour did you expect:
The second
assert
should fail becausedata
ismalloc
ed with 1 byte and shouldn't be readable up to 128 bytes.What happened instead:
CBMC reports that the program is valid -- all implicit and explicit assertions pass. I have used all the CBMC
-check
flags that I thought could be relevant in this context.Additional information:
With the
--smt2
flag, CBMC does report an assertion failure at the last line ofmain
and also within the__CPROVER_r_ok
check, as expected.This bug is related to, but is different from, #5952. There we actually read the same length as we allocated, so the failure from
--smt2
is unexpected. In this report, success from the SAT-based solver is unexpected.The text was updated successfully, but these errors were encountered: