Skip to content

Commit

Permalink
Fix of ParentIdx mismatch for DebugTypeInheritance in SPIRV.debug.h (K…
Browse files Browse the repository at this point in the history
…hronosGroup#2490)

Fixed ParentIdx was mismatched for DebugTypeInheritance type in context of NonSemantic.Shader.DebugInfo.100. That lead to heap buffer overflow in SPIRVExtInst::getExtOp getter when instruction was incorrectly casted
to SPIRVExtInst as parent of the culprit instruction in SPIRVToLLVMDbgTran::getDIBuilder. The missmatch happen because in previous used standard OpenCL.DebugInfo.100 DebugTypeInheritance had Child field as zero indexed argument. In newer standard that field is removed.
  • Loading branch information
bwlodarcz authored Apr 16, 2024
1 parent 0d83f22 commit c6e9fea
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 30 deletions.
37 changes: 25 additions & 12 deletions lib/SPIRV/LLVMToSPIRVDbgTran.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
//
//===----------------------------------------------------------------------===//
#include "LLVMToSPIRVDbgTran.h"
#include "SPIRV.debug.h"
#include "SPIRVWriter.h"

#include "llvm/IR/DebugInfo.h"
Expand Down Expand Up @@ -1052,20 +1053,32 @@ LLVMToSPIRVDbgTran::transDbgMemberTypeNonSemantic(const DIDerivedType *MT) {

SPIRVEntry *LLVMToSPIRVDbgTran::transDbgInheritance(const DIDerivedType *DT) {
using namespace SPIRVDebug::Operand::TypeInheritance;
const SPIRVWord Offset = isNonSemanticDebugInfo() ? 1 : 0;
SPIRVWordVec Ops(OperandCount - Offset);
// There is no Child operand in NonSemantic debug spec
if (!isNonSemanticDebugInfo())
Ops[ChildIdx] = transDbgEntry(DT->getScope())->getId();
Ops[ParentIdx - Offset] = transDbgEntry(DT->getBaseType())->getId();
unsigned ParentIdx, OffsetIdx, SizeIdx, FlagsIdx, OperandCount;
if (isNonSemanticDebugInfo()) {
ParentIdx = NonSemantic::ParentIdx;
OffsetIdx = NonSemantic::OffsetIdx;
SizeIdx = NonSemantic::SizeIdx;
FlagsIdx = NonSemantic::FlagsIdx;
OperandCount = NonSemantic::OperandCount;
} else {
ParentIdx = OpenCL::ParentIdx;
OffsetIdx = OpenCL::OffsetIdx;
SizeIdx = OpenCL::SizeIdx;
FlagsIdx = OpenCL::FlagsIdx;
OperandCount = OpenCL::OperandCount;
}
SPIRVWordVec Ops(OperandCount);
Ops[ParentIdx] = transDbgEntry(DT->getBaseType())->getId();
ConstantInt *OffsetInBits = getUInt(M, DT->getOffsetInBits());
Ops[OffsetIdx - Offset] =
SPIRVWriter->transValue(OffsetInBits, nullptr)->getId();
Ops[OffsetIdx] = SPIRVWriter->transValue(OffsetInBits, nullptr)->getId();
ConstantInt *Size = getUInt(M, DT->getSizeInBits());
Ops[SizeIdx - Offset] = SPIRVWriter->transValue(Size, nullptr)->getId();
Ops[FlagsIdx - Offset] = transDebugFlags(DT);
if (isNonSemanticDebugInfo())
transformToConstant(Ops, {FlagsIdx - Offset});
Ops[SizeIdx] = SPIRVWriter->transValue(Size, nullptr)->getId();
Ops[FlagsIdx] = transDebugFlags(DT);
if (isNonSemanticDebugInfo()) {
transformToConstant(Ops, {FlagsIdx});
} else {
Ops[OpenCL::ChildIdx] = transDbgEntry(DT->getScope())->getId();
}
return BM->addDebugInfo(SPIRVDebug::TypeInheritance, getVoidTy(), Ops);
}

Expand Down
46 changes: 31 additions & 15 deletions lib/SPIRV/SPIRVToLLVMDbgTran.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
//===----------------------------------------------------------------------===//

#include "SPIRVToLLVMDbgTran.h"
#include "SPIRV.debug.h"
#include "SPIRVEntry.h"
#include "SPIRVFunction.h"
#include "SPIRVInstruction.h"
Expand Down Expand Up @@ -1214,32 +1215,47 @@ DINode *SPIRVToLLVMDbgTran::transTypedef(const SPIRVExtInst *DebugInst) {

DINode *SPIRVToLLVMDbgTran::transTypeInheritance(const SPIRVExtInst *DebugInst,
DIType *ChildClass) {
if (isNonSemanticDebugInfo(DebugInst->getExtSetKind()) && !ChildClass) {
// Will be translated later when processing TypeMember's parent
return nullptr;
}
using namespace SPIRVDebug::Operand::TypeInheritance;
// The value is used when assertions are enabled
[[maybe_unused]] unsigned OperandCount;
unsigned ParentIdx, OffsetIdx, FlagsIdx;
if (isNonSemanticDebugInfo(DebugInst->getExtSetKind())) {
if (!ChildClass) {
// Will be translated later when processing TypeMember's parent
return nullptr;
}
OperandCount = NonSemantic::OperandCount;
ParentIdx = NonSemantic::ParentIdx;
OffsetIdx = NonSemantic::OffsetIdx;
FlagsIdx = NonSemantic::FlagsIdx;
} else {
OperandCount = NonSemantic::OperandCount;
ParentIdx = OpenCL::ParentIdx;
OffsetIdx = OpenCL::OffsetIdx;
FlagsIdx = OpenCL::FlagsIdx;
}
const SPIRVWordVec &Ops = DebugInst->getArguments();
assert(Ops.size() >= MinOperandCount && "Invalid number of operands");
// No Child operand for NonSemantic debug spec
SPIRVWord Offset = isNonSemanticDebugInfo(DebugInst->getExtSetKind()) ? 1 : 0;
assert(Ops.size() >= OperandCount && "Invalid number of operands");
DIType *Parent =
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[ParentIdx - Offset]));
DIType *Child =
isNonSemanticDebugInfo(DebugInst->getExtSetKind())
? ChildClass
: transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[ChildIdx]));
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[ParentIdx]));
DINode::DIFlags Flags = DINode::FlagZero;
SPIRVWord SPIRVFlags = getConstantValueOrLiteral(Ops, FlagsIdx - Offset,
DebugInst->getExtSetKind());
SPIRVWord SPIRVFlags =
getConstantValueOrLiteral(Ops, FlagsIdx, DebugInst->getExtSetKind());
if ((SPIRVFlags & SPIRVDebug::FlagAccess) == SPIRVDebug::FlagIsPublic)
Flags |= llvm::DINode::FlagPublic;
if ((SPIRVFlags & SPIRVDebug::FlagAccess) == SPIRVDebug::FlagIsProtected)
Flags |= llvm::DINode::FlagProtected;
if ((SPIRVFlags & SPIRVDebug::FlagAccess) == SPIRVDebug::FlagIsPrivate)
Flags |= llvm::DINode::FlagPrivate;
uint64_t OffsetVal =
BM->get<SPIRVConstant>(Ops[OffsetIdx - Offset])->getZExtIntValue();
BM->get<SPIRVConstant>(Ops[OffsetIdx])->getZExtIntValue();
DIType *Child;
if (isNonSemanticDebugInfo(DebugInst->getExtSetKind())) {
Child = ChildClass;
} else {
Child =
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[OpenCL::ChildIdx]));
}
return getDIBuilder(DebugInst).createInheritance(Child, Parent, OffsetVal, 0,
Flags);
}
Expand Down
19 changes: 16 additions & 3 deletions lib/SPIRV/libSPIRV/SPIRV.debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,17 +503,27 @@ enum {
} // namespace TypeMember

namespace TypeInheritance {
namespace NonSemantic {
enum {
ParentIdx = 0,
OffsetIdx = 1,
SizeIdx = 2,
FlagsIdx = 3,
OperandCount = 4
};
}

namespace OpenCL {
enum {
ChildIdx = 0,
ParentIdx = 1,
OffsetIdx = 2,
SizeIdx = 3,
FlagsIdx = 4,
// NonSemantic
MinOperandCount = 4,
OperandCount = 5
};
}
} // namespace TypeInheritance

namespace TypePtrToMember {
enum {
Expand Down Expand Up @@ -991,7 +1001,10 @@ inline bool hasDbgInstParentScopeIdx(
ParentScopeIdx = TypeMember::OpenCL::ParentIdx;
return true;
case SPIRVDebug::TypeInheritance:
ParentScopeIdx = TypeInheritance::ParentIdx;
if (ExtKind == SPIRV::SPIRVEIS_OpenCL_DebugInfo_100)
ParentScopeIdx = TypeInheritance::OpenCL::ParentIdx;
else
ParentScopeIdx = TypeInheritance::NonSemantic::ParentIdx;
return true;
case SPIRVDebug::TypePtrToMember:
ParentScopeIdx = TypePtrToMember::ParentIdx;
Expand Down

0 comments on commit c6e9fea

Please sign in to comment.