Skip to content

Commit efafe3c

Browse files
YixingZhang007sys-ce-bb
authored andcommitted
Add Check for WordCount Against SPIRV File Size (#3266)
A check is inserted in `parseAndCreateSPIRVEntry` function to ensure the `WordCount` for the current SPIR-V instruction is not smaller than the remaining input stream size. If the stream does not contain enough data for the specified `WordCount`, an SPIRV error of `InvalidWordCount` is raised. Original commit: KhronosGroup/SPIRV-LLVM-Translator@43a5855e317d145
1 parent 1eda567 commit efafe3c

File tree

4 files changed

+26
-4
lines changed

4 files changed

+26
-4
lines changed

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2089,7 +2089,10 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
20892089
<< "have (" << MaxNumElements << "). Should the array be "
20902090
<< "split?\n Original LLVM value:\n"
20912091
<< toString(GV);
2092-
getErrorLog().checkError(false, SPIRVEC_InvalidWordCount, SS.str());
2092+
getErrorLog().checkError(false, SPIRVEC_InvalidWordCount,
2093+
"Can't encode instruction with word count "
2094+
"greater than 65535:\n" +
2095+
SS.str());
20932096
}
20942097
}
20952098
}

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,10 @@ class SPIRVEntry {
412412
std::stringstream SS;
413413
SS << "Id: " << Id << ", OpCode: " << OpCodeNameMap::map(OpCode)
414414
<< ", Name: \"" << Name << "\"\n";
415-
getErrorLog().checkError(false, SPIRVEC_InvalidWordCount, SS.str());
415+
getErrorLog().checkError(
416+
false, SPIRVEC_InvalidWordCount,
417+
"Can't encode instruction with word count greater than 65535:\n" +
418+
SS.str());
416419
}
417420
}
418421
void validateFunctionControlMask(SPIRVWord FCtlMask) const;

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVErrorEnum.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ _SPIRV_OP(InvalidLlvmModule, "Invalid LLVM module:")
1616
_SPIRV_OP(UnimplementedOpCode, "Unimplemented opcode")
1717
_SPIRV_OP(FunctionPointers, "Can't translate function pointer:\n")
1818
_SPIRV_OP(InvalidInstruction, "Can't translate llvm instruction:\n")
19-
_SPIRV_OP(InvalidWordCount,
20-
"Can't encode instruction with word count greater than 65535:\n")
19+
_SPIRV_OP(InvalidWordCount, "")
2120
_SPIRV_OP(Requires1_1, "Feature requires SPIR-V 1.1 or greater:")
2221
_SPIRV_OP(RequiresVersion, "Cannot fulfill SPIR-V version restriction:\n")
2322
_SPIRV_OP(RequiresExtension,

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2374,6 +2374,23 @@ SPIRVEntry *parseAndCreateSPIRVEntry(SPIRVWord &WordCount, Op &OpCode,
23742374
if (WordCount == 0 || OpCode == OpNop) {
23752375
return nullptr;
23762376
}
2377+
if (!SPIRVUseTextFormat) {
2378+
std::streampos CurrentPos = IS.tellg();
2379+
IS.seekg(0, std::ios::end);
2380+
std::streamoff RemainingBytes = IS.tellg() - CurrentPos;
2381+
IS.clear();
2382+
IS.seekg(CurrentPos);
2383+
std::streamoff ExpectedBytes =
2384+
static_cast<std::streamoff>((WordCount - 1) * sizeof(SPIRVWord));
2385+
if (RemainingBytes < ExpectedBytes) {
2386+
M.getErrorLog().checkError(
2387+
false, SPIRVEC_InvalidWordCount,
2388+
"WordCount exceeds remaining input stream size: expected size = " +
2389+
std::to_string(ExpectedBytes) + " bytes, remaining size = " +
2390+
std::to_string(RemainingBytes) + " bytes");
2391+
M.setInvalid();
2392+
}
2393+
}
23772394
SPIRVEntry *Entry = SPIRVEntry::create(OpCode);
23782395
assert(Entry);
23792396
Entry->setModule(&M);

0 commit comments

Comments
 (0)