Skip to content
This repository was archived by the owner on Oct 3, 2021. It is now read-only.
This repository was archived by the owner on Oct 3, 2021. It is now read-only.

geo1-ll.c can overflow #1289

@hernanponcedeleon

Description

@hernanponcedeleon

The following program can overflow

int main() {
    int z, k;
    long long x, y, c;
    z = __VERIFIER_nondet_int();
    k = __VERIFIER_nondet_int();
    assume_abort_if_not(z >= 1);
    assume_abort_if_not(k >= 1);

    x = 1;
    y = z;
    c = 1;

    while (1) {
        __VERIFIER_assert(x*z - x - y + 1 == 0);

        if (!(c < k)) 
            break;

        c = c + 1;
        x = x * z + 1;
        y = y * z;

    }  //geo1

    x = x * (z - 1);

    __VERIFIER_assert(1 + x - y == 0);
    return 0;
}

Let z = 2147483647. After the first while iteration

x = 2147483648
y = 2147483647

After the second iteration

x = 4611686014132420610
y = 4611686014132420609

The overflow can happen in the next iteration when the multiplication x*z happens inside the first __VERIFIER_assert.

The overflow is confirmed by CBMC if I replace the non deterministic values by 2147483647

cbmc --signed-overflow-check git/sv-benchmarks/c/nla-digbench/geo1-ll.c -unwind 2
CBMC version 5.11 (cbmc-5.11) 64-bit x86_64 macos
Parsing git/sv-benchmarks/c/nla-digbench/geo1-ll.c
Converting
Type-checking geo1-ll
Generating GOTO Program
Adding CPROVER library (x86_64)
Removal of function pointers and virtual functions
Generic Property Instrumentation
Running with 8 object bits, 56 offset bits (default)
Starting Bounded Model Checking
Unwinding loop main.0 iteration 1 file git/sv-benchmarks/c/nla-digbench/geo1-ll.c line 34 function main thread 0
Not unwinding loop main.0 iteration 2 file git/sv-benchmarks/c/nla-digbench/geo1-ll.c line 34 function main thread 0
size of program expression: 99 steps
simple slicing removed 10 assignments
Generated 20 VCC(s), 20 remaining after simplification
Passing problem to propositional reduction
converting SSA
Running propositional reduction
Post-processing
Solving with MiniSAT 2.2.1 with simplifier
396 variables, 143 clauses
SAT checker: instance is SATISFIABLE
Solving with MiniSAT 2.2.1 with simplifier
396 variables, 0 clauses
SAT checker inconsistent: instance is UNSATISFIABLE
Runtime decision procedure: 0.00125636s

** Results:
git/sv-benchmarks/c/nla-digbench/geo1-ll.c function reach_error
[reach_error.assertion.1] line 9 assertion 0: SUCCESS

git/sv-benchmarks/c/nla-digbench/geo1-ll.c function main
[main.overflow.1] line 35 arithmetic overflow on signed * in x * (signed long int)z: SUCCESS
[main.overflow.2] line 35 arithmetic overflow on signed - in x * (signed long int)z - x: SUCCESS
[main.overflow.3] line 35 arithmetic overflow on signed - in (x * (signed long int)z - x) - y: SUCCESS
[main.overflow.4] line 35 arithmetic overflow on signed + in ((x * (signed long int)z - x) - y) + (signed long int)1: SUCCESS
[main.overflow.5] line 40 arithmetic overflow on signed + in c + (signed long int)1: SUCCESS
[main.overflow.6] line 41 arithmetic overflow on signed * in x * (signed long int)z: SUCCESS
[main.overflow.7] line 41 arithmetic overflow on signed + in x * (signed long int)z + (signed long int)1: SUCCESS
[main.overflow.8] line 42 arithmetic overflow on signed * in y * (signed long int)z: FAILURE
[main.overflow.9] line 46 arithmetic overflow on signed - in z - 1: SUCCESS
[main.overflow.10] line 46 arithmetic overflow on signed * in x * (signed long int)(z - 1): SUCCESS
[main.overflow.11] line 48 arithmetic overflow on signed + in (signed long int)1 + x: SUCCESS
[main.overflow.12] line 48 arithmetic overflow on signed - in ((signed long int)1 + x) - y: SUCCESS

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

What I'm not sure is what would be the best solution for these kind of overflows due to big ints multiplications (I suspect the same problem happens in other benchmarks).

In this particular case, one possibility would be to restrict the value of k (which bounds the number of iterations) to something rather small (e.g. 6) and the value of z to something "big" but which could not overflow given the bound of k (e.g. 1000)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions