Skip to content

Add flag to check pointer validity only for those pointer primitives that lack defined semantics for invalid pointers #6238

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

Closed
jimgrundy opened this issue Jul 20, 2021 · 5 comments
Labels
aws Bugs or features of importance to AWS CBMC users documentation pending merge

Comments

@jimgrundy
Copy link
Collaborator

CBMC version: 5.34.0
Operating system: N/A

The CBMC Manual section on “Memory Primitives / Detecting potential misuses of memory primitives” (http://cprover.diffblue.com/memory-primitives.html#autotoc_md108) ends with the following text:

"While the first three primitives [__CPROVER_POINTER_OBJECT, __CPROVER_POINTER_OFFSET, and __CPROVER_same_object] have well-defined semantics even on invalid pointers, using them on invalid pointers is usually unintended in user programs. Thus, they have been included in the --pointer-primitive-check option."

We are encountering various cases where it is our intention to use these primitives on invalid pointers — specifically as assumptions about uninitialized pointers so as to constrain them. For example, we may malloc one pointer p and then seek to constrain a second pointer q to point into the same region as p.

To facilitate this without abandoning the pointer primitive checks entirely we need the addition of a new flag that causes CBMC to check for valid pointer use only on those primitives where behavior on invalid pointers is undefined. One possible name might be --lax-pointer-primitive-check. There are probably better ones.

It should be possible to use both this new flag (--lax-pointer-primitive-check) and the existing flag (--pointer-primitive-check) such that a #pragma can be used to disable just the stricter checks on a region of code.

@feliperodri feliperodri added the aws Bugs or features of importance to AWS CBMC users label Jul 20, 2021
@feliperodri
Copy link
Collaborator

We need to be careful while using these primitives in assumptions (see #6057). Instead of creating a new flag, we might want to consider updating the behavior of these primitives to properly handle invalid pointers (see the discussion #6045 (comment)). For instance, consider the following code snippet:

int *a = malloc(sizeof(*a));
int *b;
__CPROVER_assume(__CPROVER_same_object(a, b));
assert(__CPROVER_r_ok(a, sizeof(*a)));
assert(__CPROVER_r_ok(b, sizeof(*b)));

I'd assume that without the pointer primitive check, both assertions should be valid.

@feliperodri
Copy link
Collaborator

cc. @SaswatPadhi

@jimgrundy
Copy link
Collaborator Author

We need to be careful while using these primitives in assumptions (see #6057). Instead of creating a new flag, we might want to consider updating the behavior of these primitives to properly handle invalid pointers (see the discussion #6045 (comment)). For instance, consider the following code snippet:

int *a = malloc(sizeof(*a));
int *b;
__CPROVER_assume(__CPROVER_same_object(a, b));
assert(__CPROVER_r_ok(a, sizeof(*a)));
assert(__CPROVER_r_ok(b, sizeof(*b)));

I'd assume that without the pointer primitive check, both assertions should be valid.

@jimgrundy jimgrundy reopened this Jul 20, 2021
@jimgrundy
Copy link
Collaborator Author

Sorry, didn't mean to close this issue, just close a comment window I had open. I'll get used to this interface.

Above, "__CPROVER_assume(__CPROVER_same_object(a, b));" may be insufficient to cause "b" to be a valid pointer, since while this constrains the object-id component of the pointer it does not constrain the offset component, and -ve offsets are used mark invalid pointers (from what I read in the manual), so you may have to make some further assumption that b's offset was non-negative. After that, I would expect the 2nd assertion to fail because b's offset may be such that it places b outside the range of the allocated region.

@jimgrundy
Copy link
Collaborator Author

jimgrundy commented Jul 23, 2021

Daniel's take on this is that, in fact, these three predicates dot no act correctly when used on invalid pointers, and so that issue here is not that we should have a new flag that would allow them to be so called, but rather that we should fix the documentation to say that they cannot.

vmihalko pushed a commit to vmihalko/cbmc that referenced this issue Jan 24, 2022
pointer_object, pointer_offset have well-defined behaviour even when the
input is an unconstrained pointer: the result is equally unconstrained.

Regression tests are updated to reflect the reduced number of checks
generated by --pointer-primitive-check.

Note that the patterns in pointer-primitive-check-03 never were
effective as they were placed in the patterns-not-to-seen section of
test.desc while also missing proper parenthesis escaping (making the
patterns trivially non-matching).

Fixes: diffblue#6238
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aws Bugs or features of importance to AWS CBMC users documentation pending merge
Projects
None yet
Development

No branches or pull requests

4 participants