Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions runtime/executor/tensor_parser_exec_aten.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ ET_NODISCARD Error validateTensorLayout(
"Dim mismatch. Expected %d, got %zu.",
dim,
expected_layout.sizes().size());
ET_CHECK_OR_RETURN_ERROR(
s_tensor->dim_order()->size() == static_cast<size_t>(dim),
InvalidExternalData,
"Dim order size mismatch. Expected %d, got %zu.",
dim,
s_tensor->dim_order()->size());
Comment on lines +132 to +137
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TensorLayout::create returns a Result<const TensorLayout>, but this function calls s_tensor->dim_order()->size() and later s_tensor->dim_order()->Get(i) without first checking that s_tensor->dim_order() is non-null. If a malformed or tampered flatbuffer omits the dim_order field, these dereferences will crash instead of returning Error::InvalidExternalData; consider adding an ET_CHECK_OR_RETURN_ERROR that s_tensor->sizes() != nullptr and s_tensor->dim_order() != nullptr (similar to the checks in tensor_parser_aten.cpp) before using them.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

@lucylq lucylq Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is validated before going into validateTensorLayout, see: https://github.com/pytorch/executorch/blob/main/runtime/executor/tensor_parser_aten.cpp#L69
https://github.com/pytorch/executorch/blob/main/runtime/executor/tensor_parser_portable.cpp#L73

^ before calling getTensorDataPtr, which calls validateTensorLayout

for (int i = 0; i < dim; i++) {
ET_CHECK_OR_RETURN_ERROR(
s_tensor->sizes()->Get(i) == expected_layout.sizes()[i],
Expand Down
35 changes: 35 additions & 0 deletions runtime/executor/test/tensor_parser_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <executorch/extension/data_loader/file_data_loader.h>
#include <executorch/runtime/core/exec_aten/exec_aten.h>
#include <executorch/runtime/core/tensor_layout.h>
#include <executorch/runtime/executor/test/managed_memory_manager.h>
#include <executorch/schema/program_generated.h>

Expand All @@ -23,7 +24,10 @@ using executorch::runtime::EValue;
using executorch::runtime::FreeableBuffer;
using executorch::runtime::Program;
using executorch::runtime::Result;
using executorch::runtime::Span;
using executorch::runtime::TensorLayout;
using executorch::runtime::deserialization::parseTensor;
using executorch::runtime::deserialization::validateTensorLayout;
using executorch::runtime::testing::ManagedMemoryManager;
using torch::executor::util::FileDataLoader;

Expand Down Expand Up @@ -188,3 +192,34 @@ TEST_F(TensorParserTest, TestMutableState) {
}
ASSERT_EQ(num_mutable_tensors, 2);
}

// Tests that validateTensorLayout rejects tensors where dim_order is shorter
// than sizes, preventing out-of-bounds reads.
TEST(ValidateTensorLayoutTest, DimOrderSizeMismatchIsRejected) {
flatbuffers::FlatBufferBuilder builder;

std::vector<int32_t> sizes = {2, 3, 4};
std::vector<uint8_t> dim_order_short = {0};

auto tensor_offset = executorch_flatbuffer::CreateTensor(
builder,
executorch_flatbuffer::ScalarType::FLOAT,
0,
builder.CreateVector(sizes),
builder.CreateVector(dim_order_short));
builder.Finish(tensor_offset);

const auto* s_tensor = flatbuffers::GetRoot<executorch_flatbuffer::Tensor>(
builder.GetBufferPointer());

std::vector<int32_t> expected_sizes = {2, 3, 4};
std::vector<uint8_t> expected_dim_order = {0, 1, 2};
auto layout = TensorLayout::create(
Span<const int32_t>(expected_sizes.data(), expected_sizes.size()),
Span<const uint8_t>(expected_dim_order.data(), expected_dim_order.size()),
ScalarType::Float);
Comment thread
lucylq marked this conversation as resolved.
ASSERT_TRUE(layout.ok());

EXPECT_EQ(
validateTensorLayout(s_tensor, layout.get()), Error::InvalidExternalData);
}
Loading