Skip to content

Validate num_channels against tensor sizes in FILTER_BANK kernel#3602

Open
adilburaksen wants to merge 1 commit into
tensorflow:mainfrom
adilburaksen:fix-filterbank-num-channels-oob
Open

Validate num_channels against tensor sizes in FILTER_BANK kernel#3602
adilburaksen wants to merge 1 commit into
tensorflow:mainfrom
adilburaksen:fix-filterbank-num-channels-oob

Conversation

@adilburaksen

@adilburaksen adilburaksen commented Jun 18, 2026

Copy link
Copy Markdown

BUG=out-of-bounds read/write in FILTER_BANK kernel from unvalidated num_channels

What

The FILTER_BANK signal kernel takes its channel count from the op's init flexbuffer
(num_channels) and six runtime tensors. FilterBankInit reads num_channels and allocates a
work area of num_channels + 1; FilterbankAccumulateChannels then loops num_channels + 1 times,
reading channel_frequency_starts[i], channel_weight_starts[i] and channel_widths[i] and writing
num_channels output elements.

FilterBankPrepare validated only the rank and type of each tensor — never that num_channels is
consistent with the per-channel metadata tensor lengths or the output length. A model whose flexbuffer
declares a num_channels larger than those tensors therefore caused an out-of-bounds read.

This was confirmed with AddressSanitizer two ways:

  • a kernel unit test (32-channel flexbuffer with 17-element metadata tensors), and
  • loading a real audio_preprocessor_int8.tflite (with a single byte changed so num_channels = 80,
    metadata tensors left at 41) through GetModel() + MicroInterpreter + Invoke(), which reads off
    the end of the model buffer inside FilterbankAccumulateChannels.

This is the same class of bug, and the same num_channels-vs-tensor-size check, that was added for the
sibling FilterBankSpectralSubtraction kernel in #3594; filter_bank.cc was not covered there.

Change

  • filter_bank.cc: FilterBankPrepare now checks num_channels > 0, that
    channel_frequency_starts, channel_weight_starts and channel_widths each have
    num_channels + 1 elements, and that the output has num_channels elements.
  • filter_bank_test.cc: regression test that the mismatched model is rejected (no OOB).

No change for valid models.

@adilburaksen adilburaksen requested a review from a team as a code owner June 18, 2026 22:41
FilterBankInit reads num_channels from the op's init flexbuffer and allocates a
work area of (num_channels + 1) * sizeof(uint64_t); FilterbankAccumulateChannels
then loops num_channels + 1 times, indexing channel_frequency_starts[i],
channel_weight_starts[i] and channel_widths[i] and writing num_channels output
elements. FilterBankPrepare validated only the rank and type of each tensor,
never that num_channels is consistent with the per-channel metadata tensor
lengths or the output length, so a model whose flexbuffer declares a num_channels
larger than those tensors caused an out-of-bounds read. On targets where size_t
is 32 bits, a large num_channels also overflows the work-area size computation
into a tiny allocation that the accumulation loop then writes past
(out-of-bounds write). Both were confirmed with AddressSanitizer.

Reject an out-of-range num_channels in FilterBankInit, and validate in
FilterBankPrepare that num_channels > 0, that the metadata tensors each have
num_channels + 1 elements, and that the output has num_channels elements
(mirroring the recent fix for the sibling FilterBankSpectralSubtraction kernel),
plus a regression test.
@adilburaksen adilburaksen force-pushed the fix-filterbank-num-channels-oob branch from a1e52b2 to 46adb06 Compare June 18, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant