You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

TFLite BITCAST INT8-to-INT4 CPU Out-of-Bounds Write PoC

malicious_bitcast_int4_oob.tflite is a structurally valid TFL3 model. During normal CPU inference, its built-in BITCAST operation copies a 4,096-byte INT8 constant into an INT4 output tensor that TFLite allocated as 2,048 packed bytes. The remaining 2,048 bytes write past the destination; in the supplied TensorFlow 2.21 CPU reproduction, they overwrite an adjacent live sentinel allocation.

This is not a malformed FlatBuffer or a crash-only test. The model has a benign, caller-provided INT8 sentinel tensor immediately after the BITCAST output. The proof verifies that exactly its first 2,048 bytes change from -91 to the model-owned constant byte 0x55 (85), while the remainder stays unchanged. The INT8 control is byte-for-byte equivalent in graph structure and differs only in the first BITCAST output type; it leaves the 4,096-byte sentinel untouched.

Files

  • malicious_bitcast_int4_oob.tflite โ€” the uploadable PoC model.
  • control_bitcast_int8.tflite โ€” matching non-vulnerable control model.
  • build_and_verify.py โ€” regenerates both valid models and proves the overwrite.
  • verify_report.json โ€” concise results from fresh CPU verification.
  • source_citations.md and duplicate_check.md โ€” root-cause and duplicate-gate notes.

Reproduction

Use CPU TensorFlow 2.21.0. No NVIDIA GPU, custom op, malformed model, or external file is required.

python -m pip install -r requirements.txt
python build_and_verify.py

The script runs each model through both the normal default tf.lite.Interpreter path and BUILTIN_WITHOUT_DEFAULT_DELEGATES. Expected assertions:

  • Control: output-to-sentinel span = 4,096 bytes; changed sentinel bytes = 0.
  • Malicious model: output-to-sentinel span = 2,048 bytes; changed sentinel bytes = 2,048; indices 0 through 2,047 change to 85.

For the direct byte-loading API, run:

python build_and_verify.py --model-content

Root cause

tensorflow/lite/kernels/bitcast.cc compares the input and output logical element sizes through GetSizeOfType() and accepts INT8 and INT4 as equal-size values. It then executes memcpy(output->data.data, input->data.data, input->bytes) without ensuring that the packed INT4 destination has at least input->bytes storage.

TFLite deliberately reports an INT4 logical element as one byte for shape handling, but its separate BytesRequired() allocation routine packs two INT4 elements per byte. Consequently, an INT4 tensor of shape [4096] has a 2,048-byte arena allocation while the INT8 input remains 4,096 bytes. The unchecked memcpy writes 2,048 bytes beyond the destination during inference.

See source_citations.md for exact upstream source locations.

Downloads last month
9
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support