Validate SPIRV Version number when parsing binary header (#3834)
Fixes #3831
diff --git a/source/binary.cpp b/source/binary.cpp
index f16bf52..75a997d 100644
--- a/source/binary.cpp
+++ b/source/binary.cpp
@@ -45,6 +45,14 @@
// 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);
diff --git a/test/binary_header_get_test.cpp b/test/binary_header_get_test.cpp
index f8f6bdb..3ce0b63 100644
--- a/test/binary_header_get_test.cpp
+++ b/test/binary_header_get_test.cpp
@@ -81,5 +81,37 @@
}
}
+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
diff --git a/test/link/binary_version_test.cpp b/test/link/binary_version_test.cpp
index 0ceeeba..80aab0f 100644
--- a/test/link/binary_version_test.cpp
+++ b/test/link/binary_version_test.cpp
@@ -27,21 +27,21 @@
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 @@
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