Skip to content

Commit 4c1ae3c

Browse files
authored
Fix crash in array length validation (#6500)
Fixes: https://crbug.com/ossfuzz/476507591 * Don't get the bitwidth until the type is checked
1 parent 8ac4c4f commit 4c1ae3c

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

source/val/validate_memory.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2127,9 +2127,14 @@ spv_result_t ValidateArrayLength(ValidationState_t& state,
21272127
// 64-bit requires CapabilityShader64BitIndexingEXT or a pipeline/shader
21282128
// flag and is validated in VVL.
21292129
const uint32_t result_type_id = inst->type_id();
2130+
if (!state.IsIntScalarTypeWithSignedness(result_type_id, 0)) {
2131+
return state.diag(SPV_ERROR_INVALID_ID, inst)
2132+
<< "The Result Type of Op" << spvOpcodeString(opcode) << " <id> "
2133+
<< state.getIdName(inst->id())
2134+
<< " must be OpTypeInt with width 32 or 64 and signedness 0.";
2135+
}
21302136
const uint32_t result_type_width = state.GetBitWidth(inst->type_id());
2131-
if (!state.IsIntScalarTypeWithSignedness(result_type_id, 0) ||
2132-
(result_type_width != 32 && result_type_width != 64)) {
2137+
if (result_type_width != 32 && result_type_width != 64) {
21332138
return state.diag(SPV_ERROR_INVALID_ID, inst)
21342139
<< "The Result Type of Op" << spvOpcodeString(opcode) << " <id> "
21352140
<< state.getIdName(inst->id())

test/val/val_memory_test.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,34 @@ TEST_F(ValidateMemory, ArrayLenResultNotIntType) {
604604
"0\n"));
605605
}
606606

607+
TEST_F(ValidateMemory, ArrayLenResultUnsizedPointer) {
608+
std::string spirv = R"(
609+
OpCapability ClipDistance
610+
OpMemoryModel Logical GLSL450
611+
OpName %65312 "arrayLen"
612+
%void = OpTypeVoid
613+
%8 = OpTypeFunction %void
614+
%float = OpTypeFloat 32
615+
%v2float = OpTypeVector %float 2
616+
%_struct_5 = OpTypeStruct %v2float
617+
%_ptr_Uniform__struct_5 = OpTypePointer Uniform %_struct_5
618+
%6 = OpVariable %_ptr_Uniform__struct_5 Uniform
619+
%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
620+
%2105376 = OpFunction %void None %8
621+
%8224 = OpLabel
622+
%65312 = OpArrayLength %_ptr_Uniform_v2float %6 538976288
623+
OpUnreachable
624+
OpFunctionEnd
625+
)";
626+
627+
CompileSuccessfully(spirv.c_str());
628+
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
629+
EXPECT_THAT(
630+
getDiagnosticString(),
631+
HasSubstr("The Result Type of OpArrayLength <id> '1[%arrayLen]' must be "
632+
"OpTypeInt with width 32 or 64 and signedness 0."));
633+
}
634+
607635
TEST_F(ValidateMemory, ArrayLenResultNot32bits) {
608636
std::string spirv = R"(
609637
OpCapability Shader

0 commit comments

Comments
 (0)