Klee-replay fails! Signed integer overflow
liushengahn opened this issue · comments
- I'm using KLEE-replay to reproduce an execution path. However, after running it, I found that the replayed path differs from the original execution path. The reason is that the addition of two negative values overflowed and became a positive value, leading to an error in the path reproduction.
- Steps to reproduce the bug:
example:
#include "assert.h"
#include "klee/klee.h"
int main() {
int a, b, c, d, x, y, z;
klee_make_symbolic(&a, sizeof(a), "a");
klee_make_symbolic(&b, sizeof(b), "b");
klee_make_symbolic(&c, sizeof(c), "c");
klee_make_symbolic(&d, sizeof(d), "d");
klee_make_symbolic(&x, sizeof(x), "x");
klee_make_symbolic(&y, sizeof(y), "y");
klee_make_symbolic(&z, sizeof(z), "z");
if (a > 10) {
z = 5;
} else {
z = 10;
}
if (b > 0) {
d = 1;
} else {
d = 0;
}
c = a + b;
if (c < 60) {
x = x + 1;
if (x < 40) {
return -1;
}
}
return 0;
}
clang -I /root/klee/include -emit-llvm -c -g -O0 -Xclang -disable-O0-optnone test.c
klee test.bc
Select a Ktest where both 'a' and 'b' are very small negative values.
klee --replay-ktest-file=./klee-out-0/test000002.ktest test.bc
It will encounter an issue on the line 'c = a+b', executing the opposite branch because of integer overflow.
3. KLEE didn't have any error messages, coz the execution proceeded smoothly; however, it took the wrong branch due to the integer overflow.
I think perhaps it needs to check for overflow before performing the calculation.
I'm not sure if this is an issue?Thank you,and I looking forward to hearing from you.
Merry Christmas!"
What does "taking the wrong branch due to overflow" mean to you? For example, with a = -2147482624, b = -2147483648
I get the expected value of c = 1024
: 0x80000400 + 0x80000000 = 0x00000400
.
Using LLVM 14, the computation of c
is performed as:
%28 = add nsw i32 %26, %27, !dbg !63
KLEE currently does not support generating a poison value via the nsw
flag. However, you can use KLEE's UBSan support to detect this overflow as an error:
$ clang -I /workspaces/klee/include -emit-llvm -c -g -O0 -Xclang -disable-O0-optnone -fsanitize=undefined -fno-sanitize=local-bounds,function,vptr test.c
$ build/bin/klee --replay-ktest-file=./klee-out-0/test000001.ktest --ubsan-runtime test.bc
KLEE: output directory is "/workspaces/klee/klee-out-9"
KLEE: Using STP solver backend
KLEE: SAT solver: CryptoMiniSat
KLEE: Deterministic allocator: Using quarantine queue size 8
KLEE: Deterministic allocator: globals (start-address=0x7fd593000000 size=10 GiB)
KLEE: Deterministic allocator: constants (start-address=0x7fd313000000 size=10 GiB)
KLEE: Deterministic allocator: heap (start-address=0x7ed313000000 size=1024 GiB)
KLEE: Deterministic allocator: stack (start-address=0x7eb313000000 size=128 GiB)
KLEE: WARNING: undefined reference to function: printf
KLEE: replaying: 0x55f41752be30 (28 bytes) (1/1)
KLEE: ERROR: runtime/Sanitizer/ubsan/ubsan_handlers.cpp:37: signed-integer-overflow
KLEE: NOTE: now ignoring this error at this location
KLEE: done: total instructions = 162
KLEE: done: completed paths = 0
KLEE: done: partially completed paths = 1
KLEE: done: generated tests = 1