Skip to content

Use OBJECT_SIZE(p) for dynamic memory bounds checking #5247

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

Merged
merged 1 commit into from
Feb 28, 2020

Conversation

danpoe
Copy link
Contributor

@danpoe danpoe commented Feb 26, 2020

This changes the dynamic memory bounds checking predicate in address_check().
It now uses OBJECT_SIZE() instead of the variables __CPROVER_malloc_size and
__CPROVER_malloc_object that are set in the malloc() model. This also means that
the predicates __CPROVER_r_ok()/__CPROVER_w_ok() will be more precise. In the
previous approach, the following assertion could not be proven for example:

void main() { char *c = malloc(1); assert(!__CPROVER_r_ok(c, 2)); }

  • Each commit message has a non-empty body, explaining why the change was made.
  • n/a Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
  • n/a The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/
  • Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
  • n/a My commit message includes data points confirming performance improvements (if claimed).
  • My PR is restricted to a single feature or bugfix.
  • n/a White-space or formatting changes outside the feature-related changed lines are in commits of their own.

@danpoe danpoe force-pushed the feature/memory-bounds-check branch 3 times, most recently from cbddb64 to 2129b2f Compare February 26, 2020 16:58
@codecov-io
Copy link

codecov-io commented Feb 26, 2020

Codecov Report

Merging #5247 into develop will decrease coverage by 0.01%.
The diff coverage is 100%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #5247      +/-   ##
===========================================
- Coverage    67.42%   67.41%   -0.02%     
===========================================
  Files         1162     1162              
  Lines        95637    95637              
===========================================
- Hits         64484    64473      -11     
- Misses       31153    31164      +11
Flag Coverage Δ
#cproversmt2 42.56% <100%> (-0.02%) ⬇️
#regression 63.94% <100%> (-0.02%) ⬇️
#unit 31.9% <0%> (ø) ⬆️
Impacted Files Coverage Δ
src/analyses/goto_check.cpp 79.45% <100%> (ø) ⬆️
src/util/pointer_predicates.cpp 55% <0%> (-13.75%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update cd2c65b...8f0f289. Read the comment docs.

@danpoe danpoe force-pushed the feature/memory-bounds-check branch 3 times, most recently from 0d509c9 to 8f0f289 Compare February 27, 2020 11:21
Copy link
Contributor

@thk123 thk123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't say I really understand much about the code change, but the tests look robust. I assume it is already tested, but it is worth having a test using --pointer-check and so some dynamically allocated memory?

{
int *x = malloc(2);
int *y = malloc(2);
assert(__CPROVER_r_ok(x, 3) == __CPROVER_r_ok(y, 3));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Not sure I understand the purpose of the test

Copy link
Contributor Author

@danpoe danpoe Feb 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was reported in issue #5194. It checks that two uses of __CPROVER_r_ok() can return false simultaneously. Previously only one call could return false at a time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Please add to the desc file 🙂

assert(__CPROVER_r_ok(p, 2));
assert(!__CPROVER_r_ok(p, 2));

assert(__CPROVER_r_ok(p, 3));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice - not obvious so good to check it works

@danpoe danpoe added the aws Bugs or features of importance to AWS CBMC users label Feb 28, 2020
@danpoe danpoe force-pushed the feature/memory-bounds-check branch from 8f0f289 to f1fa849 Compare February 28, 2020 14:02
@danpoe
Copy link
Contributor Author

danpoe commented Feb 28, 2020

@thk123 Ok, addressed all the comments.

Copy link
Contributor

@thk123 thk123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks - looks great.

simultaneously in the encoding of the program. Previously, at most one call
could be false at a time. This was imprecise, however, it was sufficient to
guarantee soundness when the __CPROVER_r_ok() primitive was used directly in an
assertion (i.e., as assert(__CPROVER_r_ok(p, size)).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could link to the relevant issue so people can find more context

^EXIT=10$
^SIGNAL=0$
--
^warning: ignoring
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⛏️ Still missing an explanation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one is simple enough to not need an explanation

@danpoe danpoe force-pushed the feature/memory-bounds-check branch from f1fa849 to e05d813 Compare February 28, 2020 15:47
This changes the dynamic memory bounds checking predicate in address_check().
It now uses OBJECT_SIZE() instead of the variables __CPROVER_malloc_size and
__CPROVER_malloc_object that are set in the malloc() model. This also means that
the predicates __CPROVER_r_ok()/__CPROVER_w_ok() will be more precise. In the
previous approach, the following assertion could not be proven for example:

void main() { char *c = malloc(1); assert(!__CPROVER_r_ok(c, 2)); }
@danpoe danpoe merged commit 8a24f79 into diffblue:develop Feb 28, 2020
@danpoe danpoe deleted the feature/memory-bounds-check branch June 2, 2020 17:06
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants