Skip to content
Open
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 tensorflow/lite/micro/kernels/circular_buffer_common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ TfLiteStatus CircularBufferPrepare(TfLiteContext* context, TfLiteNode* node) {
TF_LITE_ENSURE_EQ(context, 1, input->dims->data[1]);
TF_LITE_ENSURE_EQ(context, input->dims->data[2], output->dims->data[2]);
TF_LITE_ENSURE_EQ(context, output->dims->data[3], input->dims->data[3]);
// The number of slots in the circular buffer (output->dims->data[1]) must be
// at least 1. CircularBufferEval computes the shift size as
// (num_slots - 1) * depth and passes it to memmove; a num_slots of 0 makes
// that size negative, which wraps to a huge size_t and causes an
// out-of-bounds read/write on the output tensor.
TF_LITE_ENSURE(context, output->dims->data[1] >= 1);

TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type);

Expand Down
23 changes: 23 additions & 0 deletions tensorflow/lite/micro/kernels/circular_buffer_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,27 @@ TEST(CircularBufferTest, Reset) {
EXPECT_EQ(kTfLiteOk, runner.Invoke());
}

TEST(CircularBufferTest, ZeroNumSlotsRejectedInPrepare) {
// With num_slots == 0, CircularBufferEval computes the buffer shift size as
// (num_slots - 1) * depth, which is negative and wraps to a huge size_t when
// passed to memmove, causing an out-of-bounds read/write on the output
// tensor. Since all dimensions come from the model, Prepare must reject a
// zero slot count.
int8_t in = 0, out = 0;
int in_dims[] = {4, 1, 1, 1, 1}, out_dims[] = {4, 1, 0, 1, 1};
TfLiteTensor tensors[] = {
tflite::testing::CreateQuantizedTensor(
&in, tflite::testing::IntArrayFromInts(in_dims), 1, 0),
tflite::testing::CreateQuantizedTensor(
&out, tflite::testing::IntArrayFromInts(out_dims), 1, 0),
};
int ins[] = {1, 0}, outs[] = {1, 1};
tflite::micro::KernelRunner runner(
*tflite::Register_CIRCULAR_BUFFER(), tensors, 2,
tflite::testing::IntArrayFromInts(ins),
tflite::testing::IntArrayFromInts(outs), nullptr);

EXPECT_NE(kTfLiteOk, runner.InitAndPrepare());
}

TF_LITE_MICRO_TESTS_MAIN