KLEE missing an error on symbolic array access
salvadorer opened this issue · comments
Hi,
I detected the following issue in KLEE:
I compiled the code below with clang -I ~/klee/include -emit-llvm -c -g -O0 -Xclang -disable-O0-optnone test.c
:
#include "klee/klee.h"
#include <assert.h>
int main (int argc, char* argv[]) {
int d1;
int d2;
int *d3;
int arr[1] = {0};
int var = klee_int("var");
klee_assume(0x32DAE895 < var);
int i = klee_int("i");
klee_assume(var < arr[i]);
assert(0);
}
If I now invoke klee --silent-klee-assume --emit-all-errors --solver-backend=stp test.bc
, I see a non-deterministic behavior: In some cases (roughly 20%) I see:
$ klee --silent-klee-assume --emit-all-errors --solver-backend=stp test.bc
KLEE: output directory is "klee-out-1"
KLEE: Using STP solver backend
KLEE: SAT solver: MiniSat
KLEE: Deterministic allocator: Using quarantine queue size 8
KLEE: Deterministic allocator: globals (start-address=0x7f0fbf1cd000 size=10 GiB)
KLEE: Deterministic allocator: constants (start-address=0x7f0d3f1cd000 size=10 GiB)
KLEE: Deterministic allocator: heap (start-address=0x7e0d3f1cd000 size=1024 GiB)
KLEE: Deterministic allocator: stack (start-address=0x7ded3f1cd000 size=128 GiB)
KLEE: ERROR: test.c:12: memory error: out of bound pointer
KLEE: ERROR: test.c:13: ASSERTION FAIL: 0
KLEE: done: total instructions = 162
KLEE: done: completed paths = 0
KLEE: done: partially completed paths = 10
KLEE: done: generated tests = 2
In the other case, the warning about the assertion is missed. I'd expect a warning about the assertion in each case as for i=0
the assertion does not hold.
I'm working on an Ubuntu platform and klee --version gives:
KLEE 3.1-pre (https://klee.github.io)
Build mode: RelWithDebInfo (Asserts: ON)
Build revision: unknown
Ubuntu LLVM version 14.0.0
Optimized build.
Default target: x86_64-pc-linux-gnu
Host CPU: znver3
I'd expect a warning about the assertion in each case as for i=0
arr[i]
can point anywhere in memory and sometimes resolves to a valid object (e.g. d1
).
I see a non-deterministic behavior
You can fix the start addresses for the deterministic allocator (e.g. --kdalloc-constants-start-address
) and than it should be deterministic.
I understand that the assertion might fail non-deterministically depending on whether the previous assumption evaluates to true or false (in turn depending on what arr[i] points to). However, doesn't KLEE branch on the bounds check, ensuring that i will also have value 0, and therefore, make the assertion fail?
ensuring that i will also have value 0
But then
klee_assume(var < arr[i]);
would boil down (roughly) to
klee_assume(0x32DAE895 < 0);
This check fails and cannot reach the assert or what do you mean?
True, this makes sense.
Thanks for your help!