From eab9c17714244936d8bb9a18105da13717c94b1e Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 5 Aug 2022 09:07:30 +0000 Subject: [PATCH] Fix stack-buffer-overflow in generated code When generating code for a local, we were using the LLVM type for the allocation. However, we were assuming that the allocation was sized according to the julia datatype size. These two sizes do not match, as the julia size is rounded up to alignment, causing a stack buffer overflow. --- src/codegen.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 2f3974c3a5110..a47c8631cf6f8 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4341,7 +4341,7 @@ static jl_cgval_t emit_varinfo(jl_codectx_t &ctx, jl_varinfo_t &vi, jl_sym_t *va } else { // copy value to a non-mutable (non-volatile SSA) location - AllocaInst *varslot = cast(vi.value.V); + AllocaInst *varslot = cast(vi.value.V->stripPointerCasts()); Type *T = varslot->getAllocatedType(); assert(!varslot->isArrayAllocation() && "variables not expected to be VLA"); AllocaInst *ssaslot = cast(varslot->clone()); @@ -4721,7 +4721,7 @@ static void emit_upsilonnode(jl_codectx_t &ctx, ssize_t phic, jl_value_t *val) } else if (vi.value.V && !vi.value.constant && vi.value.typ != jl_bottom_type) { assert(vi.value.ispointer()); - Type *T = cast(vi.value.V)->getAllocatedType(); + Type *T = cast(vi.value.V->stripPointerCasts())->getAllocatedType(); if (CountTrackedPointers(T).count) { // make sure gc pointers (including ptr_phi of union-split) are initialized to NULL ctx.builder.CreateStore(Constant::getNullValue(T), vi.value.V, true); @@ -7055,7 +7055,12 @@ static jl_llvm_functions_t Type *vtype = julia_type_to_llvm(ctx, jt, &isboxed); assert(!isboxed); assert(!type_is_ghost(vtype) && "constants should already be handled"); - Value *lv = new AllocaInst(vtype, M->getDataLayout().getAllocaAddrSpace(), jl_symbol_name(s), /*InsertBefore*/ctx.topalloca); + Type *alloc_type = ArrayType::get(getInt8Ty(ctx.builder.getContext()), jl_datatype_size(jt)); + Value *lv = new AllocaInst(alloc_type, M->getDataLayout().getAllocaAddrSpace(), nullptr, + Align(jl_datatype_align(jt)), jl_symbol_name(s), /*InsertBefore*/ctx.topalloca); +#ifndef JL_LLVM_OPAQUE_POINTERS + lv = new BitCastInst(lv, PointerType::get(vtype, M->getDataLayout().getAllocaAddrSpace()), "", /*InsertBefore*/ctx.topalloca); +#endif if (CountTrackedPointers(vtype).count) { StoreInst *SI = new StoreInst(Constant::getNullValue(vtype), lv, false, Align(sizeof(void*))); SI->insertAfter(ctx.topalloca);