From dfd2aea9e73c00634f81c6388587713ad737d4b7 Mon Sep 17 00:00:00 2001 From: Lukáš Zaoral Date: Sat, 25 Mar 2023 18:33:46 +0100 Subject: 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 ``` --- lib/Core/Executor.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'lib') 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. -- cgit 1.4.1