66 * LICENSE file in the root directory of this source tree.
77 */
88
9+ #include < cinttypes> // @donotremove
10+
911#include < c10/util/safe_numerics.h>
1012#include < executorch/runtime/core/error.h>
1113#include < executorch/runtime/core/exec_aten/exec_aten.h>
@@ -58,13 +60,20 @@ Result<size_t> calculate_nbytes(
5860 executorch::aten::ScalarType scalar_type) {
5961 size_t n = 1 ;
6062 for (size_t i = 0 ; i < sizes.size (); i++) {
63+ ET_CHECK_OR_RETURN_ERROR (
64+ sizes[i] >= 0 ,
65+ InvalidProgram,
66+ " Invalid size[%zu]: %" PRId32 " . Size must not be negative" ,
67+ i,
68+ sizes[i]);
6169 size_t next_n;
6270 bool overflow =
6371 c10::mul_overflows (n, static_cast <size_t >(sizes[i]), &next_n);
6472 ET_CHECK_OR_RETURN_ERROR (
6573 !overflow,
6674 InvalidArgument,
67- " Invalid size[%zu]: %d. Potentially overflowed, expect to be 0 or n: %zu" ,
75+ " Invalid size[%zu]: %" PRId32
76+ " . Potentially overflowed, expect to be 0 or n: %zu" ,
6877 i,
6978 sizes[i],
7079 n);
@@ -185,7 +194,20 @@ Result<TensorInfo> MethodMeta::input_tensor_meta(size_t index) const {
185194 index);
186195 auto input_index = s_plan_->inputs ()->Get (index);
187196 // input_index was already validated by input_tag().
188- auto tensor_value = s_plan_->values ()->Get (input_index)->val_as_Tensor ();
197+ auto serialization_value = s_plan_->values ()->Get (input_index);
198+ ET_CHECK_OR_RETURN_ERROR (
199+ serialization_value != nullptr ,
200+ InvalidProgram,
201+ " Null value for input %zu at index %d" ,
202+ index,
203+ input_index);
204+ auto tensor_value = serialization_value->val_as_Tensor ();
205+ ET_CHECK_OR_RETURN_ERROR (
206+ tensor_value != nullptr && tensor_value->sizes () != nullptr &&
207+ tensor_value->dim_order () != nullptr ,
208+ InvalidProgram,
209+ " Null tensor metadata for input %zu" ,
210+ index);
189211 return TensorInfo::create (
190212 Span<const int32_t >(
191213 tensor_value->sizes ()->data (), tensor_value->sizes ()->size ()),
@@ -236,8 +258,20 @@ Result<TensorInfo> MethodMeta::output_tensor_meta(size_t index) const {
236258 index);
237259 auto output_index = s_plan_->outputs ()->Get (index);
238260 // output_index was already validated by output_tag().
239- auto tensor_value = s_plan_->values ()->Get (output_index)->val_as_Tensor ();
240-
261+ auto serialization_value = s_plan_->values ()->Get (output_index);
262+ ET_CHECK_OR_RETURN_ERROR (
263+ serialization_value != nullptr ,
264+ InvalidProgram,
265+ " Null value for output %zu at index %d" ,
266+ index,
267+ output_index);
268+ auto tensor_value = serialization_value->val_as_Tensor ();
269+ ET_CHECK_OR_RETURN_ERROR (
270+ tensor_value != nullptr && tensor_value->sizes () != nullptr &&
271+ tensor_value->dim_order () != nullptr ,
272+ InvalidProgram,
273+ " Null tensor metadata for output %zu" ,
274+ index);
241275 return TensorInfo::create (
242276 Span<const int32_t >(
243277 tensor_value->sizes ()->data (), tensor_value->sizes ()->size ()),
@@ -257,7 +291,10 @@ size_t MethodMeta::num_attributes() const {
257291 auto value = values->Get (i);
258292 if (value->val_type () == executorch_flatbuffer::KernelTypes::Tensor) {
259293 auto tensor_value = value->val_as_Tensor ();
260- if (tensor_value->extra_tensor_info () != nullptr &&
294+ if (tensor_value != nullptr &&
295+ tensor_value->extra_tensor_info () != nullptr &&
296+ tensor_value->extra_tensor_info ()->fully_qualified_name () !=
297+ nullptr &&
261298 tensor_value->extra_tensor_info ()->fully_qualified_name ()->c_str () !=
262299 nullptr ) {
263300 ++counter;
@@ -274,10 +311,19 @@ Result<TensorInfo> MethodMeta::attribute_tensor_meta(size_t index) const {
274311 auto value = values->Get (i);
275312 if (value->val_type () == executorch_flatbuffer::KernelTypes::Tensor) {
276313 auto tensor_value = value->val_as_Tensor ();
277- if (tensor_value->extra_tensor_info () != nullptr &&
314+ if (tensor_value != nullptr &&
315+ tensor_value->extra_tensor_info () != nullptr &&
316+ tensor_value->extra_tensor_info ()->fully_qualified_name () !=
317+ nullptr &&
278318 tensor_value->extra_tensor_info ()->fully_qualified_name ()->c_str () !=
279319 nullptr ) {
280320 if (counter == index) {
321+ ET_CHECK_OR_RETURN_ERROR (
322+ tensor_value->sizes () != nullptr &&
323+ tensor_value->dim_order () != nullptr ,
324+ InvalidProgram,
325+ " Null tensor metadata for attribute %zu" ,
326+ index);
281327 auto t_name =
282328 tensor_value->extra_tensor_info ()->fully_qualified_name ();
283329 // Count constant returns as memory planned
@@ -322,7 +368,14 @@ Result<int64_t> MethodMeta::memory_planned_buffer_size(size_t index) const {
322368 num_buffers);
323369 // Index zero is reserved internally, and we hide it from users. Adjust the
324370 // provided index to point to one of the actual buffers.
325- return s_plan_->non_const_buffer_sizes ()->Get (index + 1 );
371+ int64_t size = s_plan_->non_const_buffer_sizes ()->Get (index + 1 );
372+ ET_CHECK_OR_RETURN_ERROR (
373+ size >= 0 ,
374+ InvalidProgram,
375+ " memory_planned_buffer_size(%zu) has invalid negative size: %" PRId64,
376+ index,
377+ size);
378+ return size;
326379}
327380
328381bool MethodMeta::uses_backend (const char * backend_name) const {
0 commit comments