Skip to content

Commit d06e1bd

Browse files
TristanInSecTristan Madani
andcommitted
Add overflow checks to reduce-nd workspace size computation
The workspace size for reduce operations is computed by multiplying normalized input shape dimensions as size_t values. On 32-bit platforms, this can overflow to zero or a small value, causing an undersized workspace allocation that the reduction kernel then writes past. Add __builtin_mul_overflow checks to both the innermost and non-innermost reduction paths, returning xnn_status_invalid_parameter when the workspace size would overflow. Co-Authored-By: Tristan Madani <tristmd+ai@gmail.com>
1 parent fda2410 commit d06e1bd

1 file changed

Lines changed: 20 additions & 4 deletions

File tree

src/operators/reduce-nd.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,16 @@ static enum xnn_status reshape_reduce_nd(
241241
size_t num_reduction_elements;
242242
if (normalized_reduction_axes[num_reduction_axes - 1] == num_input_dims - 1) {
243243
if (workspace_size != NULL) {
244-
const size_t num_output_elements = normalized_input_shape[0] * normalized_input_shape[2] * normalized_input_shape[4];
245-
*workspace_size = (num_output_elements << log2_accumulator_element_size) + XNN_EXTRA_BYTES;
244+
size_t num_output_elements;
245+
size_t tmp;
246+
if (__builtin_mul_overflow(normalized_input_shape[0], normalized_input_shape[2], &tmp) ||
247+
__builtin_mul_overflow(tmp, normalized_input_shape[4], &num_output_elements) ||
248+
__builtin_mul_overflow(num_output_elements, (size_t)1 << log2_accumulator_element_size, &tmp)) {
249+
xnn_log_error("failed to reshape %s operator: workspace size overflow",
250+
xnn_operator_type_to_string_v2(reduce_op));
251+
return xnn_status_invalid_parameter;
252+
}
253+
*workspace_size = tmp + XNN_EXTRA_BYTES;
246254
}
247255
num_reduction_elements = normalized_input_shape[1] * normalized_input_shape[3] * normalized_input_shape[5];
248256
const size_t axis_dim = normalized_input_shape[5];
@@ -283,8 +291,16 @@ static enum xnn_status reshape_reduce_nd(
283291
// Reduction along the non-innermost dimension
284292
const size_t channel_like_dim = normalized_input_shape[XNN_MAX_TENSOR_DIMS - 1];
285293
if (workspace_size != NULL) {
286-
const size_t num_output_elements = normalized_input_shape[1] * normalized_input_shape[3] * normalized_input_shape[5];
287-
*workspace_size = (num_output_elements << log2_accumulator_element_size) + XNN_EXTRA_BYTES;
294+
size_t num_output_elements;
295+
size_t tmp;
296+
if (__builtin_mul_overflow(normalized_input_shape[1], normalized_input_shape[3], &tmp) ||
297+
__builtin_mul_overflow(tmp, normalized_input_shape[5], &num_output_elements) ||
298+
__builtin_mul_overflow(num_output_elements, (size_t)1 << log2_accumulator_element_size, &tmp)) {
299+
xnn_log_error("failed to reshape %s operator: workspace size overflow",
300+
xnn_operator_type_to_string_v2(reduce_op));
301+
return xnn_status_invalid_parameter;
302+
}
303+
*workspace_size = tmp + XNN_EXTRA_BYTES;
288304
}
289305
num_reduction_elements = normalized_input_shape[0] * normalized_input_shape[2] * normalized_input_shape[4];
290306
const size_t axis_dim = normalized_input_shape[4];

0 commit comments

Comments
 (0)