Skip to content

Commit d42a11c

Browse files
GregoryComerfacebook-github-bot
authored andcommitted
Prevent signed integer overflow in pixel_shuffle size calculation (#16138)
Summary: The size calculation in `get_pixel_shuffle_out_target_size` can trigger signed integer overflow (UB) with very large upscale_factors. This manifested as an integer division by zero fault during fuzzing. Specifically, the calculation of `upscale_factor * upscale_factor` ([source](https://github.com/pytorch/executorch/blob/04f1e4d22383ffcbc770acf5002348e3f95082a2/kernels/portable/cpu/util/copy_ops_util.cpp#L364)) can overflow. In the motivating case, SizesType is a signed 32-bit integer and upscale_factor = 2^17. Since this is an impractically large upscale factor, I'm just adding a constraint that upscale_factor < 32768 (2^15). In theory, SizesType could be defined as less than 32 bits, but this seems unlikely in practice. Differential Revision: D88693324
1 parent 04f1e4d commit d42a11c

File tree

3 files changed

+12
-4
lines changed

3 files changed

+12
-4
lines changed

kernels/portable/cpu/op_pixel_shuffle.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,11 @@ Tensor& pixel_shuffle_out(
8484
ET_KERNEL_CHECK(ctx, tensor_is_default_dim_order(in), InvalidArgument, out);
8585
Tensor::SizesType expected_out_size[kTensorDimensionLimit];
8686
size_t expected_out_dim = 0;
87-
get_pixel_shuffle_out_target_size(
88-
in, upscale_factor, expected_out_size, &expected_out_dim);
87+
ET_KERNEL_CHECK(ctx,
88+
get_pixel_shuffle_out_target_size(
89+
in, upscale_factor, expected_out_size, &expected_out_dim),
90+
InvalidArgument,
91+
out);
8992

9093
// Make sure the output tensor is the right size.
9194
ET_KERNEL_CHECK(

kernels/portable/cpu/util/copy_ops_util.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,11 +346,14 @@ bool check_pixel_unshuffle_args(
346346
return true;
347347
}
348348

349-
void get_pixel_shuffle_out_target_size(
349+
bool get_pixel_shuffle_out_target_size(
350350
const Tensor& in,
351351
int64_t upscale_factor,
352352
executorch::aten::SizesType* out_sizes,
353353
size_t* out_ndim) {
354+
// Prevent signed integer overflow when computing upscale_factor ^ 2.
355+
ET_CHECK_OR_RETURN_FALSE(upscale_factor < 32768, "Upscale factor must be less than 32768.");
356+
354357
*out_ndim = in.dim();
355358
const executorch::aten::SizesType casted_upscale_factor = upscale_factor;
356359

@@ -366,6 +369,8 @@ void get_pixel_shuffle_out_target_size(
366369
out_sizes[i] = in.size(i) * casted_upscale_factor;
367370
i++;
368371
out_sizes[i] = in.size(i) * casted_upscale_factor;
372+
373+
return true;
369374
}
370375

371376
void get_pixel_unshuffle_out_target_size(

kernels/portable/cpu/util/copy_ops_util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ bool check_pixel_shuffle_args(
139139
int64_t upscale_factor,
140140
Tensor& out);
141141

142-
void get_pixel_shuffle_out_target_size(
142+
bool get_pixel_shuffle_out_target_size(
143143
const Tensor& in,
144144
int64_t upscale_factor,
145145
executorch::aten::SizesType* out_sizes,

0 commit comments

Comments
 (0)