From 9f34447f3ff525029ec889bf3a82b04678a9d7c0 Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Mon, 4 Nov 2019 22:12:52 -0800 Subject: [PATCH] [BPF] fix a use after free bug Commit fff2721286e1 ("[BPF] Fix CO-RE bugs with bitfields") fixed CO-RE handling bitfield issues. But the implementation introduced a use after free bug. The "Base" of the intrinsic might be freed so later on accessing the Type of "Base" might access the freed memory. The failed test case, CodeGen/BPF/CORE/offset-reloc-middle-chain.ll is exactly used to test such a case. Similarly to previous attempt to remember Metadata etc, remember "Base" pointee Alignment in advance to avoid such use after free bug. --- llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp index 41ba89f..ba7a3c8 100644 --- a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp +++ b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp @@ -117,6 +117,7 @@ public: struct CallInfo { uint32_t Kind; uint32_t AccessIndex; + uint32_t RecordAlignment; MDNode *Metadata; Value *Base; }; @@ -246,6 +247,8 @@ bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call, report_fatal_error("Missing metadata for llvm.preserve.array.access.index intrinsic"); CInfo.AccessIndex = getConstant(Call->getArgOperand(2)); CInfo.Base = Call->getArgOperand(0); + CInfo.RecordAlignment = + DL->getABITypeAlignment(CInfo.Base->getType()->getPointerElementType()); return true; } if (GV->getName().startswith("llvm.preserve.union.access.index")) { @@ -255,6 +258,8 @@ bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call, report_fatal_error("Missing metadata for llvm.preserve.union.access.index intrinsic"); CInfo.AccessIndex = getConstant(Call->getArgOperand(1)); CInfo.Base = Call->getArgOperand(0); + CInfo.RecordAlignment = + DL->getABITypeAlignment(CInfo.Base->getType()->getPointerElementType()); return true; } if (GV->getName().startswith("llvm.preserve.struct.access.index")) { @@ -264,6 +269,8 @@ bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call, report_fatal_error("Missing metadata for llvm.preserve.struct.access.index intrinsic"); CInfo.AccessIndex = getConstant(Call->getArgOperand(2)); CInfo.Base = Call->getArgOperand(0); + CInfo.RecordAlignment = + DL->getABITypeAlignment(CInfo.Base->getType()->getPointerElementType()); return true; } if (GV->getName().startswith("llvm.bpf.preserve.field.info")) { @@ -815,8 +822,7 @@ Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *Call, AccessKey += ":" + std::to_string(AccessIndex); MDNode *MDN = CInfo.Metadata; - uint32_t RecordAlignment = - DL->getABITypeAlignment(CInfo.Base->getType()->getPointerElementType()); + uint32_t RecordAlignment = CInfo.RecordAlignment; // At this stage, it cannot be pointer type. auto *CTy = cast(stripQualifiers(cast(MDN))); PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm, -- 2.7.4