Skip to content

Fix stack buffer overflows in NCHW reduce rewrite and ynnpack shim functions#9851

Open
mohammadmseet-hue wants to merge 1 commit intogoogle:masterfrom
mohammadmseet-hue:fix/nchw-reduce-overflow-and-shim-bounds
Open

Fix stack buffer overflows in NCHW reduce rewrite and ynnpack shim functions#9851
mohammadmseet-hue wants to merge 1 commit intogoogle:masterfrom
mohammadmseet-hue:fix/nchw-reduce-overflow-and-shim-bounds

Conversation

@mohammadmseet-hue
Copy link
Copy Markdown
Contributor

Summary

Fix 4 stack buffer overflow vulnerabilities caused by missing bounds checks on array copy operations.

Bug 1: rewrite_reduction_axes_for_nchw (src/subgraph/static-reduce.c:26)

original_reduction_axes is declared as int64_t[4] (32 bytes) but num_reduction_axes can be up to XNN_MAX_TENSOR_DIMS (6). The function is only called for 4-dim NCHW tensors (guarded at line 132), but xnn_define_static_reduce_v2 validates num_reduction_axes <= 6, not num_reduction_axes <= input_num_dims. With num_reduction_axes = 5 or 6, memcpy writes 40-48 bytes into a 32-byte stack buffer.

Additionally, the loop at line 31 indexes NCHW_AXES_MAPPING[4] and mask[4] with values derived from the overflowed buffer, causing further OOB reads and writes.

Fix: Clamp num_reduction_axes to 4 at the start of the function, since it only operates on 4-dimensional NCHW tensors.

Bugs 2-4: ynnpack shim missing bounds checks (ynnpack/xnnpack/subgraph.cc)

Three shim functions copy user-provided axes into stack-allocated arrays of size XNN_MAX_TENSOR_DIMS (6) without validating the count parameter:

Function Line Buffer Missing check
xnn_define_static_expand_dims 774 int32_t[6] num_new_axes <= 6
xnn_define_static_reduce 805 int64_t[6] num_reduction_axes <= 6
xnn_define_static_reduce_v2 862 int32_t[6] num_reduction_axes <= 6

The original C implementations (src/subgraph/copy.c:429, src/subgraph/static-reduce.c:257,342) validate these bounds before the copy. The ynnpack shims omit these checks, allowing stack buffer overflow when the count exceeds 6.

Fix: Add > XNN_MAX_TENSOR_DIMS bounds checks before the copy loops, matching the original C implementations.

…nctions

Bug 1: rewrite_reduction_axes_for_nchw (src/subgraph/static-reduce.c)
uses int64_t original_reduction_axes[4] (32 bytes) but copies
num_reduction_axes * sizeof(int64_t) bytes via memcpy. The function is
only called for 4-dim NCHW tensors, but num_reduction_axes can be up to
XNN_MAX_TENSOR_DIMS (6), since xnn_define_static_reduce_v2 only checks
num_reduction_axes <= 6, not num_reduction_axes <= input_num_dims. With
num_reduction_axes=5 or 6, memcpy writes 40-48 bytes into a 32-byte
stack buffer, corrupting adjacent stack memory.

Bugs 2-4: ynnpack/xnnpack/subgraph.cc shim functions
xnn_define_static_expand_dims, xnn_define_static_reduce, and
xnn_define_static_reduce_v2 copy user-provided axes into stack-allocated
arrays of size XNN_MAX_TENSOR_DIMS (6) without any bounds check on the
count parameter. The original C implementations in src/subgraph/copy.c
and src/subgraph/static-reduce.c validate num_dims/num_reduction_axes
<= XNN_MAX_TENSOR_DIMS before the copy, but the ynnpack shims omit
these checks. Passing num_new_axes or num_reduction_axes > 6 writes
past the stack buffer.

Fix: Add bounds checks before all affected memcpy/loop operations.
@mohammadmseet-hue
Copy link
Copy Markdown
Contributor Author

ASAN Traces

Bug 1: rewrite_reduction_axes_for_nchw stack buffer overflow

==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7f5756f00050
WRITE of size 48 at 0x7f5756f00050 thread T0
    #0 memcpy
    #1 rewrite_reduction_axes_for_nchw /src/subgraph/static-reduce.c:18
    #2 main

  This frame has 3 object(s):
    [32, 36) 'mask' (line 16)
    [48, 80) 'original_reduction_axes' (line 17) <== Memory access at offset 80 overflows this variable
SUMMARY: AddressSanitizer: stack-buffer-overflow in memcpy

Bugs 2-4: ynnpack shim stack buffer overflows

xnn_define_static_expand_dims (int32_t ynn_axes[6] with num_new_axes=8):

==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fde6fa00038
WRITE of size 4 at 0x7fde6fa00038 thread T0
    #0 xnn_define_static_expand_dims /ynnpack/xnnpack/subgraph.cc:774

  This frame has 1 object(s):
    [32, 56) 'ynn_axes' (line 774) <== Memory access at offset 56 overflows this variable
SUMMARY: AddressSanitizer: stack-buffer-overflow

All 4 bugs confirmed with AddressSanitizer. The root cause for bugs 2-4 is that the ynnpack shim functions omit the bounds checks present in the original C implementations.

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