Merge pull request #2034 from TheAggie/fix/shader-truncated-decode-out-of-range

fix(shader): report a truncated memory, image or export instruction as out of range
This commit is contained in:
Adrià 2026-10-10 08:08:33 +02:00 committed by GitHub
commit 56bfc4d1c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 12 additions and 5 deletions

View File

@ -596,6 +596,13 @@ int main() {
"raw compute cache eviction lost snapshot lifetime or exceeded its entry limit");
check(!expectFailure([&] { AgcDriver::DriverDetail::ReadRawComputeShader(rawAddress + 4); }).empty(), "raw compute accepted a misaligned entry");
check(!expectFailure([] { AgcDriver::DriverDetail::ReadRawComputeShader(0); }).empty(), "raw compute accepted an unmapped entry");
alignas(256) std::array<std::uint32_t, 128> straddling{};
straddling.fill(0xbf800000);
straddling[63] = 0xf4000000;
straddling[64] = 0xfa000000;
straddling[65] = 0xbf810000;
const auto straddled = AgcDriver::DriverDetail::ReadRawComputeShader(reinterpret_cast<std::uintptr_t>(straddling.data()));
check(straddled->code.size() == 66 && straddled->code[64] == 0xfa000000, "raw compute stopped at a memory instruction across its first read window");
#ifdef _WIN32
auto* mapping = static_cast<std::uint32_t*>(VirtualAlloc(nullptr, 8192, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
check(mapping != nullptr, "cannot allocate raw compute boundary test");

View File

@ -14,7 +14,7 @@ RdnaInstruction DecodeRdnaExportOp(std::span<const std::uint32_t> code, std::uin
RdnaInstruction DecodeRdnaExportOp(std::uint32_t programCounter, std::span<const std::uint32_t> code, std::uint32_t wordIndex) {
const std::size_t index = wordIndex;
if (index >= code.size() || code.size() - index < 2u) {
throw std::runtime_error("truncated export instruction");
throw std::out_of_range("truncated export instruction");
}
if (programCounter % 4u != 0u || programCounter > std::numeric_limits<std::uint32_t>::max() - 7u) {
throw std::runtime_error("invalid export program counter");

View File

@ -325,7 +325,7 @@ RdnaInstruction DecodeRdnaImageOp(std::span<const std::uint32_t> code, std::uint
RdnaInstruction DecodeRdnaMimg(std::uint32_t programCounter, std::span<const std::uint32_t> code, std::uint32_t wordIndex) {
const std::size_t index = wordIndex;
if (index >= code.size() || code.size() - index < 2u) {
throw std::runtime_error("truncated MIMG instruction");
throw std::out_of_range("truncated MIMG instruction");
}
const auto word0 = code[index];
const auto word1 = code[index + 1u];
@ -345,7 +345,7 @@ RdnaInstruction DecodeRdnaMimg(std::uint32_t programCounter, std::span<const std
const auto nsa = (word0 >> 1u) & 3u;
const auto wordCount = 2u + nsa;
if (code.size() - index < wordCount) {
throw std::runtime_error("truncated MIMG NSA payload");
throw std::out_of_range("truncated MIMG NSA payload");
}
if (programCounter % 4u != 0u || programCounter > std::numeric_limits<std::uint32_t>::max() - (wordCount * 4u - 1u)) {
throw std::runtime_error("invalid MIMG program counter");

View File

@ -696,7 +696,7 @@ void setRawWords(RdnaInstruction& instruction, std::span<const std::uint32_t> co
void requireTwoWords(std::span<const std::uint32_t> code, std::uint32_t wordIndex, std::uint32_t programCounter, const char* reason) {
const std::size_t index = wordIndex;
if (index >= code.size() || code.size() - index < 2u) {
throw std::runtime_error(reason);
throw std::out_of_range(reason);
}
if (programCounter % 4u != 0u || programCounter > std::numeric_limits<std::uint32_t>::max() - 7u) {
throw std::runtime_error("invalid memory instruction program counter");
@ -1039,7 +1039,7 @@ RdnaInstruction DecodeRdnaDs(std::uint32_t programCounter, std::span<const std::
RdnaInstruction DecodeRdnaMemoryOp(std::span<const std::uint32_t> code, std::uint32_t wordIndex) {
const auto programCounter = toProgramCounter(wordIndex);
if (static_cast<std::size_t>(wordIndex) >= code.size()) {
throw std::runtime_error("truncated memory instruction");
throw std::out_of_range("truncated memory instruction");
}
switch (code[wordIndex] >> 26u) {
case 0x36u: return DecodeRdnaDs(programCounter, code, wordIndex);