Skip to content

Fix integer truncation in deconvolution kernel_size computation#9876

Open
mohammadmseet-hue wants to merge 2 commits intogoogle:masterfrom
mohammadmseet-hue:fix/deconv-kernel-size-overflow
Open

Fix integer truncation in deconvolution kernel_size computation#9876
mohammadmseet-hue wants to merge 2 commits intogoogle:masterfrom
mohammadmseet-hue:fix/deconv-kernel-size-overflow

Conversation

@mohammadmseet-hue
Copy link
Copy Markdown
Contributor

@mohammadmseet-hue mohammadmseet-hue commented Apr 4, 2026

Summary

Systemic uint32_t integer truncation across 6 operator files. When uint32_t multiplications overflow, allocation sizes are undersized while write loops use the true (non-truncated) product, causing heap buffer overflows.

Bug 1: deconvolution-nhwc.c:286 — heap buffer overflow (ASAN confirmed)

kernel_size computed as uint32_t:

const uint32_t kernel_size = kernel_height * kernel_width;

Truncated kernel_size used for packed weights allocation (line 288-291), but pack_deconv_goki_w() receives kernel_height and kernel_width as separate size_t parameters and iterates the true product. With kh=kw=65536, kernel_size wraps to 0, allocation is 256 bytes, packing writes past it.

Same truncation on lines 284-285 (n_stride, k_stride).

ASAN output (operator API):

==ERROR: AddressSanitizer: heap-buffer-overflow
WRITE of size 4
    #8 xnn_pack_f32_deconv_goki_w packing.cc:3908
    #9 create_deconvolution2d_nhwc deconvolution-nhwc.c:344
0x512000000740 is located 0 bytes after 256-byte region

ASAN output (subgraph API — same path as TFLite XNNPACK delegate):

==ERROR: AddressSanitizer: heap-buffer-overflow
WRITE of size 4
    #8 xnn_pack_f32_deconv_goki_w packing.cc:3908
    #12 create_deconvolution_operator subgraph/deconvolution-2d.c:130
    #13 xnn_create_runtime_v4 runtime.c:700

Reachable from all xnn_create_deconvolution2d_nhwc_* APIs and from TFLite XNNPACK delegate via VisitTransposeConvNodexnn_define_deconvolution_2dxnn_create_runtime.

Bug 2: convolution-nchw.c:287 — heap buffer overflow

kernel_height * kernel_width computed in uint32_t arithmetic (both fields are uint32_t), then used to compute packed_weights_size. Packing functions iterate the true product.

Bug 3-7: pooling operators — validation bypass and wrong computation

  • average-pooling-nhwc.c (lines 61, 195, 274): pooling_size truncation bypasses zero-check and produces wrong 1/pooling_size scale factor
  • max-pooling-nhwc.c (lines 69, 444-445): pooling_size and effective_kernel truncation produces wrong padding
  • argmax-pooling-nhwc.c (line 66): pooling_size truncation bypasses zero-check

Attack vector

Crafted .tflite model → TFLite → XNNPACK delegate → TransposeConv delegated to xnn_define_deconvolution_2d()xnn_create_runtime() triggers weight packing → uint32_t truncation → heap buffer overflow with attacker-controlled weight data.

XNNPACK is used by TensorFlow Lite (Android/iOS), MediaPipe, PyTorch, ONNX Runtime, and Chrome (WebNN).

Fix

  • deconvolution-nhwc.c: Changed kernel_size, n_stride, k_stride from uint32_t to size_t, cast to size_t before multiplication
  • convolution-nchw.c: Cast to size_t before multiplication in allocation computation
  • Pooling operators: Changed pooling_size from uint32_t to uint64_t, cast before multiplication
  • max-pooling: Changed effective_kernel from uint32_t to size_t, cast before multiplication

Use size_t instead of uint32_t for kernel_size, n_stride, and k_stride
in create_deconvolution2d_nhwc() to prevent integer truncation when
kernel_height * kernel_width exceeds 2^32.

The truncated kernel_size was used to compute packed_group_weights_size
(the allocation size), while pack_deconv_goki_w() received
kernel_height and kernel_width as separate size_t parameters and
iterated the true product, causing a heap buffer overflow.
Apply the same uint32_t → size_t/uint64_t promotion to prevent
integer truncation in:

- convolution-nchw.c: kernel_height * kernel_width in packed weights
  allocation (heap overflow, same class as deconvolution bug)
- average-pooling-nhwc.c: pooling_size computation (3 sites)
- max-pooling-nhwc.c: pooling_size and effective kernel computation
- argmax-pooling-nhwc.c: pooling_size computation
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