Validate SPIRV Version number when parsing binary header (#3834)

Fixes #3831
This commit is contained in:
Ryan Harrison 2020-09-23 11:59:41 -04:00 committed by GitHub
parent 67525bded1
commit d1bb98fd48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 4 deletions

View File

@ -45,6 +45,14 @@ spv_result_t spvBinaryHeaderGet(const spv_const_binary binary,
// TODO: Validation checking?
pHeader->magic = spvFixWord(binary->code[SPV_INDEX_MAGIC_NUMBER], endian);
pHeader->version = spvFixWord(binary->code[SPV_INDEX_VERSION_NUMBER], endian);
// Per 2.3.1 version's high and low bytes are 0
if ((pHeader->version & 0x000000ff) || pHeader->version & 0xff000000)
return SPV_ERROR_INVALID_BINARY;
// Minimum version was 1.0 and max version is defined by SPV_VERSION.
if (pHeader->version < SPV_SPIRV_VERSION_WORD(1, 0) ||
pHeader->version > SPV_VERSION)
return SPV_ERROR_INVALID_BINARY;
pHeader->generator =
spvFixWord(binary->code[SPV_INDEX_GENERATOR_NUMBER], endian);
pHeader->bound = spvFixWord(binary->code[SPV_INDEX_BOUND], endian);

View File

@ -81,5 +81,37 @@ TEST_F(BinaryHeaderGet, TruncatedHeader) {
}
}
TEST_F(BinaryHeaderGet, VersionNonZeroHighByte) {
spv_header_t header;
code[1] = 0xFF010300;
spv_const_binary_t const_bin = get_const_binary();
ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, &header));
}
TEST_F(BinaryHeaderGet, VersionNonZeroLowByte) {
spv_header_t header;
code[1] = 0x000103F0;
spv_const_binary_t const_bin = get_const_binary();
ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, &header));
}
TEST_F(BinaryHeaderGet, VersionTooLow) {
spv_header_t header;
code[1] = 0x00000300;
spv_const_binary_t const_bin = get_const_binary();
ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, &header));
}
TEST_F(BinaryHeaderGet, VersionTooHigh) {
spv_header_t header;
code[1] = 0x000F0300;
spv_const_binary_t const_bin = get_const_binary();
ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, &header));
}
} // namespace
} // namespace spvtools

View File

@ -27,21 +27,21 @@ TEST_F(BinaryVersion, LinkerChoosesMaxSpirvVersion) {
spvtest::Binaries binaries = {
{
SpvMagicNumber,
0x00000300u,
0x00010300u,
SPV_GENERATOR_CODEPLAY,
1u, // NOTE: Bound
0u // NOTE: Schema; reserved
},
{
SpvMagicNumber,
0x00000600u,
0x00010500u,
SPV_GENERATOR_CODEPLAY,
1u, // NOTE: Bound
0u // NOTE: Schema; reserved
},
{
SpvMagicNumber,
0x00000100u,
0x00010100u,
SPV_GENERATOR_CODEPLAY,
1u, // NOTE: Bound
0u // NOTE: Schema; reserved
@ -53,7 +53,7 @@ TEST_F(BinaryVersion, LinkerChoosesMaxSpirvVersion) {
ASSERT_EQ(SPV_SUCCESS, Link(binaries, &linked_binary));
EXPECT_THAT(GetErrorMessage(), std::string());
EXPECT_EQ(0x00000600u, linked_binary[1]);
EXPECT_EQ(0x00010500u, linked_binary[1]);
}
} // namespace