Description
The textual tensor input path accepts shapes whose dimension product is larger than the 64-bit device-size range. In iree_hal_buffer_compute_view_size, element_count is multiplied by each dimension without an overflow check. On a 64-bit build, the products 2^64 and 2^64 + 1 wrap to zero and one, respectively. iree-run-module then returns success for inputs that declare approximately 2^64 elements and proceeds with a zero- or one-byte buffer allocation.
This report demonstrates an under-sized allocation request produced by the size calculation. It does not claim that an out-of-bounds read or write has already occurred because the minimal sink module does not consume the resulting buffer.
Related upstream context
IREE #3844 tracks the broader audit of iree_host_size_t/iree_device_size_t arithmetic and recommends saturating or checked math in the runtime. This report is a concrete buffer-view parsing and allocation-size instance of that broader concern: it provides a public iree-run-module --input reproducer, distinguishes arithmetic wraparound from a controlled RESOURCE_EXHAUSTED allocation failure, and does not claim to be a duplicate of the general audit. If preferred, this report can be handled as a focused follow-up to #3844.
Steps to reproduce
Save the following as sink.mlir:
func.func @main(%arg0: !hal.buffer_view) {
return
}
Compile it with the local backend:
iree-compile \
--iree-hal-target-device=local \
--iree-hal-local-target-device-backends=vmvx \
sink.mlir -o sink.vmfb
Run the following inputs:
iree-run-module --device=local-sync --module=sink.vmfb --function=main \
--input='4xf32=1,2,3,4'
iree-run-module --device=local-sync --module=sink.vmfb --function=main \
--input='4294967296x4294967296xi8'
iree-run-module --device=local-sync --module=sink.vmfb --function=main \
--input='274177x67280421310721xi8'
iree-run-module --device=local-sync --module=sink.vmfb --function=main \
--input='272222222222222222xf32'
Expected behavior
Before invoking an allocator, IREE should detect that the shape product or byte-size computation is not representable and return a normal error such as INVALID_ARGUMENT, OUT_OF_RANGE, or RESOURCE_EXHAUSTED. The small control should be accepted, while the overflowing shapes should be rejected without silently reducing their allocation size.
Actual behavior
With an IREE build from source revision 3699452, using the local vmvx backend:
| Input |
Mathematical element count |
Observed result |
| 4xf32=1,2,3,4 |
4 |
exit 0 |
| 4294967296x4294967296xi8 |
2^64 |
exit 0 |
| 274177x67280421310721xi8 |
2^64 + 1 |
exit 0 |
| 272222222222222222xf32 |
representable but very large |
exit 1, RESOURCE_EXHAUSTED from allocator |
The two overflowing cases therefore reach successful parsing and allocation after the dimension product wraps to zero or one. The large representable case fails in the allocator, which is a controlled result rather than the reported defect.
Environment
- IREE source revision: 3699452
- Tools: iree-compile and iree-run-module from the source build
- Backend: local vmvx
- Host: 64-bit Linux
Analysis
The input follows this path:
iree-run-module --input
-> iree_tooling_parse_tensor
-> iree_hal_buffer_view_parse
-> iree_hal_buffer_compute_view_size
-> iree_hal_allocator_allocate_buffer
The size helper in runtime/src/iree/hal/buffer_view_util.c computes element_count with an unchecked multiplication over the dimensions. The current upstream implementation contains the same dimension-product pattern in buffer_view_util.c, and the related buffer-view creation path recomputes the product in buffer_view.c.
The factor pair 274177 and 67280421310721 has product 2^64 + 1, making the one-byte result distinguishable from a zero-sized wrap.
Impact
An attacker-controlled or otherwise untrusted tensor shape can be accepted while the resulting buffer size is smaller than the declared tensor requires. If a later consumer accesses the declared elements, this may lead to incorrect behavior or memory unsafety; this report only establishes the arithmetic and allocation-size defect.
Suggested fix
Use checked multiplication for the dimension product and for element-count times element-width or bit-width. Return an error before allocation whenever either computation overflows or exceeds a documented implementation limit. Apply the same checked helper consistently to buffer-view size calculation and buffer-view creation.
Disclosure
This issue description and reproducer were prepared with AI assistance.
Description
The textual tensor input path accepts shapes whose dimension product is larger than the 64-bit device-size range. In iree_hal_buffer_compute_view_size, element_count is multiplied by each dimension without an overflow check. On a 64-bit build, the products 2^64 and 2^64 + 1 wrap to zero and one, respectively. iree-run-module then returns success for inputs that declare approximately 2^64 elements and proceeds with a zero- or one-byte buffer allocation.
This report demonstrates an under-sized allocation request produced by the size calculation. It does not claim that an out-of-bounds read or write has already occurred because the minimal sink module does not consume the resulting buffer.
Related upstream context
IREE #3844 tracks the broader audit of
iree_host_size_t/iree_device_size_tarithmetic and recommends saturating or checked math in the runtime. This report is a concrete buffer-view parsing and allocation-size instance of that broader concern: it provides a publiciree-run-module --inputreproducer, distinguishes arithmetic wraparound from a controlledRESOURCE_EXHAUSTEDallocation failure, and does not claim to be a duplicate of the general audit. If preferred, this report can be handled as a focused follow-up to #3844.Steps to reproduce
Save the following as sink.mlir:
Compile it with the local backend:
Run the following inputs:
Expected behavior
Before invoking an allocator, IREE should detect that the shape product or byte-size computation is not representable and return a normal error such as INVALID_ARGUMENT, OUT_OF_RANGE, or RESOURCE_EXHAUSTED. The small control should be accepted, while the overflowing shapes should be rejected without silently reducing their allocation size.
Actual behavior
With an IREE build from source revision 3699452, using the local vmvx backend:
The two overflowing cases therefore reach successful parsing and allocation after the dimension product wraps to zero or one. The large representable case fails in the allocator, which is a controlled result rather than the reported defect.
Environment
Analysis
The input follows this path:
The size helper in runtime/src/iree/hal/buffer_view_util.c computes element_count with an unchecked multiplication over the dimensions. The current upstream implementation contains the same dimension-product pattern in buffer_view_util.c, and the related buffer-view creation path recomputes the product in buffer_view.c.
The factor pair 274177 and 67280421310721 has product 2^64 + 1, making the one-byte result distinguishable from a zero-sized wrap.
Impact
An attacker-controlled or otherwise untrusted tensor shape can be accepted while the resulting buffer size is smaller than the declared tensor requires. If a later consumer accesses the declared elements, this may lead to incorrect behavior or memory unsafety; this report only establishes the arithmetic and allocation-size defect.
Suggested fix
Use checked multiplication for the dimension product and for element-count times element-width or bit-width. Return an error before allocation whenever either computation overflows or exceeds a documented implementation limit. Apply the same checked helper consistently to buffer-view size calculation and buffer-view creation.
Disclosure
This issue description and reproducer were prepared with AI assistance.