From cdabb14e7326658d0230bea7b81c285427a7025f Mon Sep 17 00:00:00 2001 From: Github Executorch Date: Wed, 4 Mar 2026 22:21:14 -0800 Subject: [PATCH 1/3] Fix integer overflow in compute_numel() (TOB-EXECUTORCH-19) compute_numel() multiplies tensor dimensions without overflow protection. The result is used for size calculations in make_tensor_ptr() and clone_tensor_ptr(), so an overflow could lead to undersized allocations and subsequent buffer overflows. Add an ET_CHECK_MSG before each multiplication to verify that numel * sizes[i] will not exceed SSIZE_MAX. This PR was authored with the assistance of Claude. --- runtime/core/portable_type/tensor_impl.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/runtime/core/portable_type/tensor_impl.cpp b/runtime/core/portable_type/tensor_impl.cpp index 17243fca0fd..35d5490e4ee 100644 --- a/runtime/core/portable_type/tensor_impl.cpp +++ b/runtime/core/portable_type/tensor_impl.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -38,6 +39,12 @@ ssize_t compute_numel(const TensorImpl::SizesType* sizes, ssize_t dim) { "Size must be non-negative, got %zd at dimension %zd", static_cast(sizes[i]), i); + ET_CHECK_MSG( + sizes[i] == 0 || numel <= SSIZE_MAX / sizes[i], + "Overflow computing numel: %zd * %zd would overflow ssize_t at dimension %zd", + numel, + static_cast(sizes[i]), + i); numel *= sizes[i]; } return numel; From 043baf7609f15c59c40de46dc94e16d6a8eafecc Mon Sep 17 00:00:00 2001 From: Github Executorch Date: Tue, 31 Mar 2026 16:56:40 -0700 Subject: [PATCH 2/3] et check --- runtime/core/portable_type/tensor_impl.cpp | 6 ++++-- runtime/executor/tensor_parser_portable.cpp | 20 ++++++++++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/runtime/core/portable_type/tensor_impl.cpp b/runtime/core/portable_type/tensor_impl.cpp index 35d5490e4ee..a7e59595d7e 100644 --- a/runtime/core/portable_type/tensor_impl.cpp +++ b/runtime/core/portable_type/tensor_impl.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -39,13 +40,14 @@ ssize_t compute_numel(const TensorImpl::SizesType* sizes, ssize_t dim) { "Size must be non-negative, got %zd at dimension %zd", static_cast(sizes[i]), i); + ssize_t next_numel; ET_CHECK_MSG( - sizes[i] == 0 || numel <= SSIZE_MAX / sizes[i], + !c10::mul_overflows(numel, static_cast(sizes[i]), &next_numel), "Overflow computing numel: %zd * %zd would overflow ssize_t at dimension %zd", numel, static_cast(sizes[i]), i); - numel *= sizes[i]; + numel = next_numel; } return numel; } diff --git a/runtime/executor/tensor_parser_portable.cpp b/runtime/executor/tensor_parser_portable.cpp index 2fc9a2dc140..cc9cd5d4f19 100644 --- a/runtime/executor/tensor_parser_portable.cpp +++ b/runtime/executor/tensor_parser_portable.cpp @@ -8,6 +8,10 @@ #include +#include + +#include + #include #include #include @@ -118,10 +122,11 @@ Result parseTensor( dim_order = const_cast(serialized_dim_order); } - // Validate sizes before using them in case the PTE data is bad. We can't - // detect bad positive values, but we can reject negative values, which would - // otherwise panic in the TensorImpl ctor. dim_order_to_stride() will validate - // dim_order. + // Validate sizes before using them in case the PTE data is bad. Reject + // negative values and check that the product of all dimensions doesn't + // overflow ssize_t, which would otherwise abort in the TensorImpl ctor. + // dim_order_to_stride() will validate dim_order. + ssize_t numel = 1; for (flatbuffers::uoffset_t i = 0; i < dim; i++) { ET_CHECK_OR_RETURN_ERROR( sizes[i] >= 0, @@ -129,6 +134,13 @@ Result parseTensor( "Negative size[%zu] %" PRId32, static_cast(i), sizes[i]); + ssize_t next_numel; + ET_CHECK_OR_RETURN_ERROR( + !c10::mul_overflows(numel, static_cast(sizes[i]), &next_numel), + InvalidProgram, + "Overflow computing numel at dim %zu", + static_cast(i)); + numel = next_numel; } // We will remove strides from schema. From 40bfc4407bff6f99f38c55da93479b6a1ea443d1 Mon Sep 17 00:00:00 2001 From: lucylq Date: Wed, 22 Apr 2026 15:01:47 -0700 Subject: [PATCH 3/3] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- runtime/executor/tensor_parser_portable.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/runtime/executor/tensor_parser_portable.cpp b/runtime/executor/tensor_parser_portable.cpp index cc9cd5d4f19..7fdd01e8f62 100644 --- a/runtime/executor/tensor_parser_portable.cpp +++ b/runtime/executor/tensor_parser_portable.cpp @@ -8,8 +8,6 @@ #include -#include - #include #include