Limit location validation (#4467)

Fixes #4464

* Add a limit to only check up to 4096 locations to prevent excessive
  memory consumption
  * still fully validates all reasonable inputs
This commit is contained in:
alan-baker 2021-08-13 13:00:00 -04:00 committed by GitHub
parent 54524ffa6a
commit 00b106e769
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -27,6 +27,10 @@ namespace spvtools {
namespace val { namespace val {
namespace { namespace {
// Limit the number of checked locations to 4096. Multiplied by 4 to represent
// all the components. This limit is set to be well beyond practical use cases.
const uint32_t kMaxLocations = 4096 * 4;
// Returns true if \c inst is an input or output variable. // Returns true if \c inst is an input or output variable.
bool is_interface_variable(const Instruction* inst, bool is_spv_1_4) { bool is_interface_variable(const Instruction* inst, bool is_spv_1_4) {
if (is_spv_1_4) { if (is_spv_1_4) {
@ -347,6 +351,11 @@ spv_result_t GetLocationsForVariable(
uint32_t num_components = NumConsumedComponents(_, sub_type); uint32_t num_components = NumConsumedComponents(_, sub_type);
uint32_t array_location = location + (num_locations * array_idx); uint32_t array_location = location + (num_locations * array_idx);
uint32_t start = array_location * 4; uint32_t start = array_location * 4;
if (kMaxLocations <= start) {
// Too many locations, give up.
break;
}
uint32_t end = (array_location + num_locations) * 4; uint32_t end = (array_location + num_locations) * 4;
if (num_components != 0) { if (num_components != 0) {
start += component; start += component;
@ -416,6 +425,11 @@ spv_result_t GetLocationsForVariable(
} }
uint32_t start = location * 4; uint32_t start = location * 4;
if (kMaxLocations <= start) {
// Too many locations, give up.
continue;
}
uint32_t end = (location + num_locations) * 4; uint32_t end = (location + num_locations) * 4;
if (num_components != 0) { if (num_components != 0) {
start += component; start += component;