Open remi-delmas-3000 opened 1 year ago
--malloc-fail-assert
can be used to switch on the assertions for the size passed to malloc
. Alternatively if the code under analysis includes error handling for null returns from malloc
, then you can use --malloc-fail-null
to return a null
from malloc
instead of failing the assert in the model of malloc
.
@remi-delmas-3000 Can you confirm whether one or more of the already existing malloc command line arguments resolves this issue for you. For reference with version 6 we are currently discussing switching the appropriate malloc
checks on by default rather than leaving them off by default.
@thomasspriggs switching on malloc-fail-null by default is the right thing to do.
However --malloc-fail-assert silently imposes some constraints on variables used as malloc arguments and can effectively hide problems in downstream code:
int main() {
size_t size;
char *p = malloc(size);
if (size > __CPROVER_max_malloc_size) {
// a bug that depends on the value of size_t
assert(0);
}
if (!p) {
return 1;
}
/// we should only assume that `size <= __CPROVER_max_malloc_size` holds from here
return 0;
}
with --malloc-fail-assert
, the assert(0)
below is unreachable even though no constraint is explicitly added to size in the code.
with --malloc-fail-null
, it is falsifiable as expected.
On the example below, --pointer-overflow-check --unsigned-overflow-check --signed-overflow-check all pass but some of the manually written assertions fail, showing that not all possible pointer overflows are detected.
In theory
p + offset
can overflow the pointer width representation and also cause an overflow in the internal pointer representation of CBMC.The full width 64bit offset value seems preserved as long as no intermediate variable assignment occurs, even through round-trip pointer-integer-pointer conversions.
Any downstream property about pointer
q
or the variabler
would potentially be meaningless since they end up representing a different pointer value or integer value that what it came from.All problems go away if we assume that
size <= __CPROVER_max_malloc_size
.CBMC should either check that all allocations are within [0, __CPROVER_max_malloc_size], or detect all pointer overflows.
CBMC version: 5.93.0 Operating system: Exact command line resulting in the issue: cbmc --pointer-overflow-check --signed-overflow-check --unsigned-overflow-check main.c What behaviour did you expect: pointer overflow checks fail What happened instead: pointer overflow checks succeed