about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorLukáš Zaoral <lzaoral@redhat.com>2023-03-25 18:33:46 +0100
committerMartinNowack <2443641+MartinNowack@users.noreply.github.com>2023-03-27 15:27:37 +0100
commitdfd2aea9e73c00634f81c6388587713ad737d4b7 (patch)
tree49c41c960fe9bb3f62537f0833efe50a892aafa9
parent89ebbb9de69b4de83e97f068cd2cbcdb7b3d1fb9 (diff)
downloadklee-dfd2aea9e73c00634f81c6388587713ad737d4b7.tar.gz
Core/Executor: long double on i686 must be aligned to 4 bytes
According to i686 System V ABI 2.1.1, long double must be aligned to 4 bytes.
Thus, its size with padding is 12 bytes.  Prior to this change only 10 bytes
were used.

This commit fixes the following out of bound pointer access.
```
$ clang -m32 -O0 -Xclang -disable-O0-optnone -g -emit-llvm -c test/Feature/VarArgAlignment.c -o varalign.bc
$ klee varalign.bc
KLEE: output directory is "/home/lukas/klee/klee-out-19"
KLEE: Using Z3 solver backend
KLEE: WARNING: undefined reference to function: printf
KLEE: WARNING ONCE: calling external: printf(44120064, 1, 2, 3) at test/Feature/VarArgAlignment.c:23 17
i1, i2, i3: 1, 2, 3
l1: 4
i4: 5
ld1: 6.000000
KLEE: ERROR: test/Feature/VarArgAlignment.c:35: memory error: out of bound pointer
KLEE: NOTE: now ignoring this error at this location

KLEE: done: total instructions = 499
KLEE: done: completed paths = 1
KLEE: done: generated tests = 1
```
-rw-r--r--lib/Core/Executor.cpp21
1 files changed, 12 insertions, 9 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index a3f91f20..cdf012a5 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -1960,17 +1960,16 @@ void Executor::executeCall(ExecutionState &state, KInstruction *ki, Function *f,
           argWidth = arguments[k]->getWidth();
         }
 
-        if (WordSize == Expr::Int32) {
-          offsets[k] = size;
-          size += Expr::getMinBytesForWidth(argWidth);
-        } else {
 #if LLVM_VERSION_CODE >= LLVM_VERSION(11, 0)
-          MaybeAlign ma = cb.getParamAlign(k);
-          unsigned alignment = ma ? ma->value() : 0;
+        MaybeAlign ma = cb.getParamAlign(k);
+        unsigned alignment = ma ? ma->value() : 0;
 #else
-          unsigned alignment = cb.getParamAlignment(k);
+        unsigned alignment = cb.getParamAlignment(k);
 #endif
 
+        if (WordSize == Expr::Int32 && !alignment)
+          alignment = 4;
+        else {
           // AMD64-ABI 3.5.7p5: Step 7. Align l->overflow_arg_area upwards to a
           // 16 byte boundary if alignment needed by type exceeds 8 byte
           // boundary.
@@ -1981,10 +1980,14 @@ void Executor::executeCall(ExecutionState &state, KInstruction *ki, Function *f,
 
           if (!alignment)
             alignment = 8;
+        }
 
-          size = llvm::alignTo(size, alignment);
-          offsets[k] = size;
+        size = llvm::alignTo(size, alignment);
+        offsets[k] = size;
 
+        if (WordSize == Expr::Int32)
+          size += Expr::getMinBytesForWidth(argWidth);
+        else {
           // AMD64-ABI 3.5.7p5: Step 9. Set l->overflow_arg_area to:
           // l->overflow_arg_area + sizeof(type)
           // Step 10. Align l->overflow_arg_area upwards to an 8 byte boundary.