-
Notifications
You must be signed in to change notification settings - Fork 274
Malloc should fail on too large allocations #5210
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
Conversation
This may fix #4604. |
It seems that we have a few regression tests that call |
src/ansi-c/library/stdlib.c
Outdated
@@ -115,6 +115,9 @@ inline void *malloc(__CPROVER_size_t malloc_size) | |||
// realistically, malloc may return NULL, | |||
// and __CPROVER_allocate doesn't, but no one cares | |||
__CPROVER_HIDE:; | |||
// 8 is the default object bits for ANSI-C and C++ | |||
if (malloc_size >= ((__CPROVER_size_t)1<<(64-8))) |
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.
Can't the object bits size be changed on the command line with --object-bits
? and if so, this probably needs to accommodate that. Ditto for the hardcoded 64
, which would probably be wrong if --32
is specified to cbmc :-)
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.
I moved the check into goto-checker
, i.e. the stdlib.c
implemetation is unchanged, we can use the pointer-width and object-bits from config, and the whole thing is behind an option, so it won't affect the existing tests.
|
||
int main() | ||
{ | ||
int *p = malloc(SIZE_MAX); |
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.
It would also be nice to have a test for a size that is 1 byte larger than the maximum CBMC can support, and also for a size that is exactly the same as the largest CBMC can support - just to test the boundary condition.
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.
Added.
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: 640cdcc).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/143393509
Codecov Report
@@ Coverage Diff @@
## develop #5210 +/- ##
============================================
- Coverage 67.42% 31.89% -35.54%
============================================
Files 1162 910 -252
Lines 95620 79452 -16168
============================================
- Hits 64476 25338 -39138
- Misses 31144 54114 +22970
Continue to review full report at Codecov.
|
{ | ||
size_t pointer_width = sizeof(void *) * 8; | ||
size_t object_bits = 8; // by default | ||
size_t cbmc_max_alloc_size = (size_t)1 << (pointer_width - object_bits); |
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.
A really tiny nit pick, so feel free to ignore me :-) But I'd personally write this as:
size_t cbmc_max_alloc_size = ((size_t)1 << (pointer_width - object_bits))-1;
int *p2 = malloc(cbmc_max_alloc_size); // try to allocate exactly the max
just so that the variable names really do mean what they say. Ditto for the other test case - but like I say, it's a really minor nit for me to pick...
src/analyses/goto_check.h
Outdated
@@ -55,6 +56,7 @@ void goto_check( | |||
" --nan-check check floating-point for NaN\n" \ | |||
" --no-built-in-assertions ignore assertions in built-in library\n" \ | |||
" --enum-range-check checks that all enum type expressions have values in the enum range\n" /* NOLINT(whitespace/line_length) */ \ | |||
" --malloc-max-check check that CBMC can represent the allocated object of requested size" /* NOLINT(whitespace/line_length) */ \ |
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.
Is a better name for this option "malloc-size-check" ? Don't have a strong opinion.
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.
Generally looks good to me, and I like that it's moved into goto-check. Apologies for the niggle comments - take them as suggestions, and not absolute requirements.
b32032f
to
b73f968
Compare
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: b73f968).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/143440844
src/analyses/goto_check.cpp
Outdated
minus_exprt{pointer_bits, object_bits}}; | ||
add_guarded_property( | ||
binary_relation_exprt{rhs_side_effect.op0(), ID_lt, max_alloc_size}, | ||
"malloc_size < 2 ^ (pointer_width - object_size)", |
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.
object_size
-> object_id_width
?
b73f968
to
0c2c362
Compare
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.
✔️
Passed Diffblue compatibility checks (cbmc commit: 0c2c362).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/143549138
On Tue, 2020-01-07 at 06:40 -0800, Chris Ryder wrote:
Generally looks good to me, and I like that it's moved into goto-
check.
I'm not sure I do. Keeping the modelling of malloc in one place, in
the library models seems, to me, to be important. Setting CPROVER
globals to control max limits, if malloc can fail, etc. seems a more
flexible option and keeps all the modelling together.
|
9c704e8
to
c7a0d53
Compare
I see two ways to handle
|
cce4e8e
to
b31422a
Compare
e517347
to
277f2d0
Compare
There is some time regression but the CI is suddenly takes >1800s to compile (before it was ~50s). |
That's ccache. |
Do you mean that it's ccache that's timing out or that the difference between build times is caused by ccache? |
Difference in build times, I suspect. Because you've touched a few header files that are reasonably widely included, ccache is going to end up thinking it does actually need to rebuild a lot of things, rather than just pulling them from the cache. |
Since the failing Travis job did actually get as far as saving it's ccache, there's a reasonably high (by Travis standards...) that simply re-running the failed job will make it pass. |
This was my 4th attempt. |
:-s Well that sucks... |
Looking a little deeper... the previous Travis run had two of the OSX configs timeout... one of those configs got as far as saving its cache, the other didnt. This most recent Travis run has only a single Travis failure - the config that previously timed out before saving it's cache - while the config that did manage to save it's cache has now passed. So I think it is worth one more attempt to re-run the Travis jobs since I think all the configs have now saved updated caches. |
277f2d0
to
b7bfd6b
Compare
1: two new options to choose between fail by assert-then-assume and return null 2: `__CPROVER_max_malloc_size` is introduced 3: some tests for boundary conditions 4: user-level documentation
More assignments due to the `__CPROVER_malloc_max_size` and `__CPROVER_malloc_failure_mode` instantiations.
and test them to any number.
specifically the C90-style struct hack with non-flexible member.
b7bfd6b
to
6fa1464
Compare
The changes in this PR cause ~7% slow down (the CORE test suite from 1560s to 1674s). It might be avoided if we figured out how to introduce |
5a38ecf
to
6fa1464
Compare
before we were extracting the value for the symbol to be used as array size, but the initialization to the extracted value is not guaranteed to happen before the initialization of the array. So we avoid extracting this value from the snapshot altogether.
6fa1464
to
195da86
Compare
e73e6aa
to
195da86
Compare
via goto-checker with a dedicated cmdl option and a property that acknowledges pointer-width and object-size.