Skip to content

Commit a2dbd5e

Browse files
author
Github Executorch
committed
Fix TOB-EXECUTORCH-39, -42: validate tensor dimensions in XNNPACK compiler
Validate that dims array is non-null and num_dims matches the actual array size in defineTensor to prevent heap buffer overflows. Change flatbufferDimsToVector to return Result<> with null-check and per-dimension validation against a 16M limit to prevent unbounded memory allocation from malicious dimension values. Authored-with: Claude
1 parent 5e8a0df commit a2dbd5e

1 file changed

Lines changed: 43 additions & 6 deletions

File tree

backends/xnnpack/runtime/XNNCompiler.cpp

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,22 @@ Error defineTensor(
285285
}
286286

287287
ET_CHECK_OR_RETURN_ERROR(
288-
tensor_value != nullptr,
289-
Internal,
290-
"Deserialized Tensor is Null, this should never happen");
288+
tensor_value != nullptr, InvalidProgram, "Deserialized tensor is null");
289+
290+
ET_CHECK_OR_RETURN_ERROR(
291+
tensor_value->num_dims() == 0 || tensor_value->dims() != nullptr,
292+
InvalidProgram,
293+
"Tensor dims is null but num_dims is %u",
294+
tensor_value->num_dims());
295+
296+
if (tensor_value->dims() != nullptr) {
297+
ET_CHECK_OR_RETURN_ERROR(
298+
tensor_value->num_dims() == tensor_value->dims()->size(),
299+
InvalidProgram,
300+
"Tensor num_dims %u does not match dims array size %u",
301+
tensor_value->num_dims(),
302+
tensor_value->dims()->size());
303+
}
291304

292305
// Get tensor dims, here we need to use a vector in order
293306
// to properly convert the uint32_t* to size_t*
@@ -966,10 +979,14 @@ Error defineStaticTransposeNode(
966979
auto graph_node = node->xnode_union_as_XNNStaticTranspose();
967980

968981
// Get tensor dims, we need to convert the uint32_t* to size_t*
982+
ET_CHECK_OR_RETURN_ERROR(
983+
graph_node->perm() != nullptr,
984+
InvalidProgram,
985+
"StaticTranspose: perm is null");
969986
std::vector<size_t> dims_data = flatbufferDimsToVector(graph_node->perm());
970987
xnn_status status = xnn_define_static_transpose(
971988
subgraph_ptr,
972-
graph_node->num_dims(),
989+
dims_data.size(),
973990
dims_data.data(),
974991
remapped_ids.at(graph_node->input_id()),
975992
remapped_ids.at(graph_node->output_id()),
@@ -1031,6 +1048,11 @@ Error defineStaticConstantPadNode(
10311048
const fb_xnnpack::XNNStaticConstantPad* graph_node =
10321049
node->xnode_union_as_XNNStaticConstantPad();
10331050

1051+
ET_CHECK_OR_RETURN_ERROR(
1052+
graph_node->pre_paddings() != nullptr &&
1053+
graph_node->post_paddings() != nullptr,
1054+
InvalidProgram,
1055+
"StaticConstantPad: pre_paddings or post_paddings is null");
10341056
std::vector<size_t> pre_paddings_dims =
10351057
flatbufferDimsToVector(graph_node->pre_paddings());
10361058
std::vector<size_t> post_paddings_dims =
@@ -1111,11 +1133,15 @@ Error defineStaticReshapeNode(
11111133
auto graph_node = node->xnode_union_as_XNNStaticReshape();
11121134

11131135
// Get tensor dims, we need to convert the uint32_t* to size_t*
1136+
ET_CHECK_OR_RETURN_ERROR(
1137+
graph_node->new_shape() != nullptr,
1138+
InvalidProgram,
1139+
"StaticReshape: new_shape is null");
11141140
std::vector<size_t> dims_data =
11151141
flatbufferDimsToVector(graph_node->new_shape());
11161142
xnn_status status = xnn_define_static_reshape(
11171143
subgraph_ptr,
1118-
graph_node->num_dims(),
1144+
dims_data.size(),
11191145
dims_data.data(),
11201146
remapped_ids.at(graph_node->input_id()),
11211147
remapped_ids.at(graph_node->output_id()),
@@ -1406,12 +1432,23 @@ Error defineStaticSliceNode(
14061432

14071433
auto graph_node = node->xnode_union_as_XNNStaticSlice();
14081434

1435+
ET_CHECK_OR_RETURN_ERROR(
1436+
graph_node->offsets() != nullptr && graph_node->sizes() != nullptr,
1437+
InvalidProgram,
1438+
"StaticSlice: offsets or sizes is null");
14091439
std::vector<size_t> offsets = flatbufferDimsToVector(graph_node->offsets());
14101440
std::vector<size_t> sizes = flatbufferDimsToVector(graph_node->sizes());
14111441

1442+
ET_CHECK_OR_RETURN_ERROR(
1443+
offsets.size() == sizes.size(),
1444+
InvalidProgram,
1445+
"StaticSlice: offsets size %zu does not match sizes size %zu",
1446+
offsets.size(),
1447+
sizes.size());
1448+
14121449
xnn_status status = xnn_define_static_slice(
14131450
subgraph_ptr,
1414-
graph_node->num_dims(),
1451+
offsets.size(),
14151452
offsets.data(),
14161453
sizes.data(),
14171454
remapped_ids.at(graph_node->input_id()),

0 commit comments

Comments
 (0)