SPIR-V Tools fuzzer: check binary size
Adds assertions to check that the SPIR-V Tools fuzzer is not
inadvertently applied to SPIR-V binaries of an invalid size, which
guards against the fuzzer being run in a misconfigured fashion.
The CL also moves a memcpy that populates a SPIR-V binary buffer so
that the memcpy only happens when the input really is SPIR-V. This
avoids frequent redundant memory copies when fuzzing WGSL.
Change-Id: Iafccaa107ff34941d8878ed5be72a2e6d38d0f49
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/58386
Auto-Submit: Alastair Donaldson <afdx@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Alastair Donaldson <afdx@google.com>
diff --git a/fuzzers/tint_common_fuzzer.cc b/fuzzers/tint_common_fuzzer.cc
index 153cf8f..88f0107 100644
--- a/fuzzers/tint_common_fuzzer.cc
+++ b/fuzzers/tint_common_fuzzer.cc
@@ -187,7 +187,6 @@
#if TINT_BUILD_SPV_READER
std::vector<uint32_t> spirv_input(size / sizeof(uint32_t));
- std::memcpy(spirv_input.data(), data, spirv_input.size() * sizeof(uint32_t));
#endif // TINT_BUILD_SPV_READER
@@ -202,9 +201,16 @@
#endif // TINT_BUILD_WGSL_READER
#if TINT_BUILD_SPV_READER
case InputFormat::kSpv: {
- if (!spirv_input.empty()) {
- program = reader::spirv::Parse(spirv_input);
+ // `spirv_input` has been initialized with the capacity to store `size /
+ // sizeof(uint32_t)` uint32_t values. If `size` is not a multiple of
+ // sizeof(uint32_t) then not all of `data` can be copied into
+ // `spirv_input`, and any trailing bytes are discarded.
+ const size_t adjusted_size = (size / sizeof(uint32_t)) * sizeof(uint32_t);
+ std::memcpy(spirv_input.data(), data, adjusted_size);
+ if (spirv_input.empty()) {
+ return 0;
}
+ program = reader::spirv::Parse(spirv_input);
break;
}
#endif // TINT_BUILD_SPV_READER
diff --git a/fuzzers/tint_spirv_tools_fuzzer/fuzzer.cc b/fuzzers/tint_spirv_tools_fuzzer/fuzzer.cc
index c1b3d64..29af73b 100644
--- a/fuzzers/tint_spirv_tools_fuzzer/fuzzer.cc
+++ b/fuzzers/tint_spirv_tools_fuzzer/fuzzer.cc
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <cassert>
#include <memory>
#include <random>
#include <string>
@@ -99,6 +100,10 @@
size_t size,
size_t max_size,
unsigned seed) {
+ assert((size % 4) == 0 &&
+ "A valid SPIR-V binary's size must be a multiple of 4, and the "
+ "SPIR-V Tools fuzzer should only work with valid binaries.");
+
std::vector<uint32_t> binary(size / sizeof(uint32_t));
std::memcpy(binary.data(), data, size);
@@ -169,6 +174,10 @@
return 0;
}
+ assert((size % 4) == 0 &&
+ "A valid SPIR-V binary's size is a multiple of 4 bytes, and the "
+ "SPIR-V Tools fuzzer should only work with valid binaries.");
+
CommonFuzzer spv_to_wgsl(InputFormat::kSpv, OutputFormat::kWGSL);
spv_to_wgsl.EnableInspector();
spv_to_wgsl.Run(data, size);