summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYonghong Song <yhs@fb.com>2019-11-04 22:12:52 -0800
committerYonghong Song <yhs@fb.com>2019-11-04 22:20:23 -0800
commit9f34447f3ff525029ec889bf3a82b04678a9d7c0 (patch)
tree73851ef0092ae02a8bc95acf739973b66d3b26d8
parentf65493a83e3bdb402fb1dfa92bcc25707e961147 (diff)
downloadbcm5719-llvm-9f34447f3ff525029ec889bf3a82b04678a9d7c0.tar.gz
bcm5719-llvm-9f34447f3ff525029ec889bf3a82b04678a9d7c0.zip
[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.
-rw-r--r--llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp10
1 files changed, 8 insertions, 2 deletions
diff --git a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp
index 41ba89f502a..ba7a3c8e142 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<DICompositeType>(stripQualifiers(cast<DIType>(MDN)));
PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
OpenPOWER on IntegriCloud