Skip to content

Spurious pointer arithmetic errors #6705

Closed
@celinval

Description

@celinval

I have created the following test case:

#include <stddef.h>
#include <assert.h>

int* add(int* ptr, size_t offset) {
    return ptr + offset;
}

int spurious() {
    int* pin_0 = 32;
    int* pin_1 = add(pin_0, 0);
    assert(pin_0 == pin_1);
}

int expected() {
    int* pin_0 = 32;
    int* pin_1 = pin_0 + 0;
    assert(pin_0 == pin_1);
}

The functions expected and spurious are functionally equivalent. One wraps the sum into an aux function and the other one performs the sum in-place. The results of CBMC proofs are rather different for these two functions:

$ cbmc test.c --pointer-overflow-check --function spurious | tail -n 18
** Results:
test.c function add
[add.pointer_arithmetic.1] line 5 pointer arithmetic: pointer NULL in ptr + (signed long int)offset: FAILURE
[add.pointer_arithmetic.2] line 5 pointer arithmetic: pointer invalid in ptr + (signed long int)offset: SUCCESS
[add.pointer_arithmetic.3] line 5 pointer arithmetic: deallocated dynamic object in ptr + (signed long int)offset: FAILURE
[add.pointer_arithmetic.4] line 5 pointer arithmetic: dead object in ptr + (signed long int)offset: FAILURE
[add.pointer_arithmetic.5] line 5 pointer arithmetic: pointer outside object bounds in ptr + (signed long int)offset: FAILURE
[add.pointer_arithmetic.6] line 5 pointer arithmetic: invalid integer address in ptr + (signed long int)offset: FAILURE

test.c function expected
[expected.pointer_arithmetic.1] line 16 pointer arithmetic: invalid integer address in pin_0 + (signed long int)0: SUCCESS
[expected.assertion.1] line 17 assertion pin_0 == pin_1: SUCCESS

test.c function spurious
[spurious.assertion.1] line 11 assertion pin_0 == pin_1: SUCCESS

** 5 of 9 failed (2 iterations)
VERIFICATION FAILED

The result below seems more reasonable:

$ cbmc test.c --pointer-overflow-check --function expected | tail -n 18
** Results:
test.c function add
[add.pointer_arithmetic.1] line 5 pointer arithmetic: pointer NULL in ptr + (signed long int)offset: SUCCESS
[add.pointer_arithmetic.2] line 5 pointer arithmetic: pointer invalid in ptr + (signed long int)offset: SUCCESS
[add.pointer_arithmetic.3] line 5 pointer arithmetic: deallocated dynamic object in ptr + (signed long int)offset: SUCCESS
[add.pointer_arithmetic.4] line 5 pointer arithmetic: dead object in ptr + (signed long int)offset: SUCCESS
[add.pointer_arithmetic.5] line 5 pointer arithmetic: pointer outside object bounds in ptr + (signed long int)offset: SUCCESS
[add.pointer_arithmetic.6] line 5 pointer arithmetic: invalid integer address in ptr + (signed long int)offset: SUCCESS

test.c function expected
[expected.pointer_arithmetic.1] line 16 pointer arithmetic: invalid integer address in pin_0 + (signed long int)0: FAILURE
[expected.assertion.1] line 17 assertion pin_0 == pin_1: SUCCESS

test.c function spurious
[spurious.assertion.1] line 11 assertion pin_0 == pin_1: SUCCESS

** 1 of 9 failed (2 iterations)
VERIFICATION FAILED

CBMC version: 5.50.0
Operating system: Ubuntu 18.04
Exact command line resulting in the issue: cbmc test.c --pointer-overflow-check --function spurious
What behaviour did you expect: Only one failure due to "pointer arithmetic: pointer invalid".
What happened instead: Checks like NULL pointer are failing even though the pointer is not NULL.

Metadata

Metadata

Assignees

No one assigned

    Labels

    More info neededawsBugs or features of importance to AWS CBMC users

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions