From a07ec191b9602d17e4fc7caebd0362cf0b9a3b57 Mon Sep 17 00:00:00 2001 From: David Plass Date: Thu, 25 Jun 2026 11:48:29 -0700 Subject: [PATCH] Fix a fuzzer failure by making sure array sizes aren't more than 1e6 bits. This can happen in this simple case: ``` const too_big = -u32:19; const too_bit_array = sN[too_big]:-1; ``` Previously this attempted to create a bit array of almost 4e9 bits, which caused a compile-time core dump. Now, this is a type-checking-time error. PiperOrigin-RevId: 938109061 --- xls/dslx/type_system_v2/BUILD | 1 + xls/dslx/type_system_v2/fast_concretizer.cc | 6 ++++++ .../type_system_v2/inference_table_converter_impl.cc | 7 +++++++ xls/dslx/type_system_v2/type_annotation_utils.h | 5 +++++ .../typecheck_module_v2_array_tuple_test.cc | 9 +++++++++ 5 files changed, 28 insertions(+) diff --git a/xls/dslx/type_system_v2/BUILD b/xls/dslx/type_system_v2/BUILD index dd5ecfa551..f67e033541 100644 --- a/xls/dslx/type_system_v2/BUILD +++ b/xls/dslx/type_system_v2/BUILD @@ -983,6 +983,7 @@ cc_library( "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/status", "@abseil-cpp//absl/status:statusor", + "@abseil-cpp//absl/strings", ], ) diff --git a/xls/dslx/type_system_v2/fast_concretizer.cc b/xls/dslx/type_system_v2/fast_concretizer.cc index 7bdb6426a6..270d12074a 100644 --- a/xls/dslx/type_system_v2/fast_concretizer.cc +++ b/xls/dslx/type_system_v2/fast_concretizer.cc @@ -24,6 +24,7 @@ #include "absl/log/check.h" #include "absl/status/status.h" #include "absl/status/statusor.h" +#include "absl/strings/substitute.h" #include "xls/common/status/ret_check.h" #include "xls/common/status/status_macros.h" #include "xls/dslx/frontend/ast.h" @@ -53,6 +54,11 @@ class FastConcretizerImpl : public FastConcretizer, GetBool(signedness_and_bit_count->signedness)); XLS_ASSIGN_OR_RETURN(uint32_t bit_count, GetU32(signedness_and_bit_count->bit_count)); + if (bit_count > kMaxBitCount) { + return absl::InvalidArgumentError( + absl::Substitute("Bit count $0 exceeds maximum limit of $1.", + bit_count, kMaxBitCount)); + } return std::make_unique(is_signed, bit_count); } diff --git a/xls/dslx/type_system_v2/inference_table_converter_impl.cc b/xls/dslx/type_system_v2/inference_table_converter_impl.cc index d1cb64852c..06a768c6b4 100644 --- a/xls/dslx/type_system_v2/inference_table_converter_impl.cc +++ b/xls/dslx/type_system_v2/inference_table_converter_impl.cc @@ -1761,6 +1761,13 @@ class InferenceTableConverterImpl : public InferenceTableConverter, int64_t bit_count, evaluator_->EvaluateU32OrExpr(parametric_context, signedness_and_bit_count.bit_count)); + if (bit_count > kMaxBitCount) { + return TypeInferenceErrorStatusForAnnotation( + annotation->span(), annotation, + absl::Substitute("Bit count $0 exceeds maximum limit of $1.", + bit_count, kMaxBitCount), + file_table_); + } if (node) { // If resulting type is bits-like, we fabricate a simplified type // annotation for the node. diff --git a/xls/dslx/type_system_v2/type_annotation_utils.h b/xls/dslx/type_system_v2/type_annotation_utils.h index 49960432e0..5a6748af52 100644 --- a/xls/dslx/type_system_v2/type_annotation_utils.h +++ b/xls/dslx/type_system_v2/type_annotation_utils.h @@ -32,6 +32,11 @@ namespace xls::dslx { +// The maximum bit count for a type (e.g., array of bits). Too many more bits +// and the compiler itself will run out of memory. Besides, designs will likely +// not have a use case for a type with more bits than this. +inline constexpr int64_t kMaxBitCount = 1000000; + struct StructOrProcRef { const StructDefBase* def; std::vector parametrics; diff --git a/xls/dslx/type_system_v2/typecheck_module_v2_array_tuple_test.cc b/xls/dslx/type_system_v2/typecheck_module_v2_array_tuple_test.cc index c4e1927463..87a9fc50da 100644 --- a/xls/dslx/type_system_v2/typecheck_module_v2_array_tuple_test.cc +++ b/xls/dslx/type_system_v2/typecheck_module_v2_array_tuple_test.cc @@ -1813,5 +1813,14 @@ const X = A..s8:3; "is greater than end value 3"))); } +TEST(TypecheckV2Test, TooBigConstant) { + EXPECT_THAT( + R"( +const too_big = -u32:19; +const too_bit_array = sN[too_big]:-1; +)", + TypecheckFails(HasSubstr("Bit count 4294967277 exceeds maximum limit of " + "2147483647."))); +} } // namespace } // namespace xls::dslx