klee / klee

KLEE Symbolic Execution Engine

Home Page:https://klee-se.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Klee-replay fails! Signed integer overflow

liushengahn opened this issue · comments

  1. 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.
  2. 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