tint: Prevent integer overflow in IntrinsicTable

If the WGSL provided over 255 arguments, then we'd overflow the uint8_t,
and a bad candidate could be matched.

We have validation in place to ensure that user functions are not
declared with more than 255 parameters, but no validation for number of
arguments provided.

Fixed: chromium:1323605
Change-Id: I048709e8b02bdd95d5082128a1186080c79b2fc7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/90249
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Ben Clayton 2022-05-13 23:17:28 +00:00 committed by Dawn LUCI CQ
parent 8faaad9b5e
commit d8e77e2e73
2 changed files with 17 additions and 2 deletions

View File

@ -1113,11 +1113,16 @@ const IntrinsicPrototype Impl::Match(const char* intrinsic_name,
constexpr int kScorePerMatchedOpenType = 1;
constexpr int kScorePerMatchedOpenNumber = 1;
auto num_parameters = overload.num_parameters;
auto num_arguments = static_cast<decltype(num_parameters)>(args.size());
uint32_t num_parameters = static_cast<uint32_t>(overload.num_parameters);
uint32_t num_arguments = static_cast<uint32_t>(args.size());
bool overload_matched = true;
if (static_cast<uint64_t>(args.size()) >
static_cast<uint64_t>(std::numeric_limits<uint32_t>::max())) {
overload_matched = false; // No overload has this number of arguments.
}
if (num_parameters != num_arguments) {
match_score += kScorePerParamArgMismatch * (std::max(num_parameters, num_arguments) -
std::min(num_parameters, num_arguments));

View File

@ -14,6 +14,8 @@
#include "src/tint/resolver/intrinsic_table.h"
#include <utility>
#include "gmock/gmock.h"
#include "src/tint/program_builder.h"
#include "src/tint/sem/atomic.h"
@ -661,5 +663,13 @@ TEST_F(IntrinsicTableTest, MismatchCompoundOp) {
)");
}
TEST_F(IntrinsicTableTest, Err257Arguments) { // crbug.com/1323605
auto* f32 = create<sem::F32>();
std::vector<const sem::Type*> arg_tys(257, f32);
auto* result = table->Lookup(BuiltinType::kAbs, std::move(arg_tys), Source{});
ASSERT_EQ(result, nullptr);
ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
}
} // namespace
} // namespace tint::resolver