YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

ExecuTorch convolution bias malformed PTE PoC

This private triage repository contains a minimal ExecuTorch .pte model file that demonstrates an inference-time out-of-bounds read in the portable aten::convolution.out kernel.

This is a crash-only security proof of concept for coordinated disclosure. It has no persistence, networking, exfiltration, shell execution, or secondary payload.

Files

  • executorch_conv_bias_oob_read_poc.pte - malformed model file. Loading and load_method("forward") succeed; executing forward triggers the bug under ASan.
  • benign_conv_bias.pte - control model exported from the same source before mutation.
  • export_mutate_conv.py - reproduces the export and metadata mutation.
  • asan_trace_executor_runner.txt - ASan output from running the malformed PTE through ExecuTorch executor_runner.
  • benign_executor_stdout.txt / benign_executor_stderr.txt - control run output.

Hashes

benign_conv_bias.pte
SHA256 736afda680bb8bba91803005e2c7986614e31a81f6dc7fa962d7768e121870f9

executorch_conv_bias_oob_read_poc.pte
SHA256 6f58b54c4bf755dcfbc0ba3224b8eeb6845232e61361593fceaa562a7e693e53

Vulnerability Summary

The malformed model executes aten::convolution.out with:

input shape  = [1, 2, 5]
weight shape = [4, 2, 3]
bias shape   = [1]
transposed   = false
groups       = 1

The convolution has four output channels, but the bias tensor contains only one element.

The intended guard in kernels/portable/cpu/util/kernel_ops_util.cpp is mis-parenthesized:

bias.value().size(0) == transposed ? groups * weight.size(1) : weight.size(0)

It is parsed as:

(bias.value().size(0) == transposed) ? groups * weight.size(1) : weight.size(0)

For the malformed non-transposed case, this evaluates to the nonzero integer weight.size(0), so the guard accepts the one-element bias instead of comparing it against the four output channels. Execution later reads bias_ptr[out_c * element_size] for out_c > 0.

Reproduction

Tested against pytorch/executorch commit:

f5acbdb00ebc5cf06258bdadc5bab82939667366

Build an ASan-instrumented portable executor runner:

git clone https://github.com/pytorch/executorch.git
cd executorch
git checkout f5acbdb00ebc5cf06258bdadc5bab82939667366
git submodule update --init --recursive third-party/json third-party/gflags third-party/flatbuffers third-party/flatcc backends/xnnpack/third-party/FXdiv backends/xnnpack/third-party/cpuinfo backends/xnnpack/third-party/pthreadpool

python3 -m venv ../et-venv
source ../et-venv/bin/activate
python -m pip install --upgrade pip
python -m pip install torch executorch flatbuffers

cmake -S . -B cmake-asan-runner -G Ninja \
  -DPYTHON_EXECUTABLE="$PWD/../et-venv/bin/python" \
  -DCMAKE_BUILD_TYPE=Debug \
  -DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \
  -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" \
  -DEXECUTORCH_BUILD_EXECUTOR_RUNNER=ON \
  -DEXECUTORCH_BUILD_EXTENSION_RUNNER_UTIL=ON \
  -DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \
  -DEXECUTORCH_BUILD_EXTENSION_EVALUE_UTIL=ON \
  -DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=OFF \
  -DEXECUTORCH_BUILD_KERNELS_QUANTIZED=OFF \
  -DEXECUTORCH_BUILD_KERNELS_LLM=OFF \
  -DEXECUTORCH_BUILD_XNNPACK=OFF \
  -DEXECUTORCH_BUILD_CPUINFO=OFF \
  -DEXECUTORCH_BUILD_PTHREADPOOL=OFF \
  -DEXECUTORCH_BUILD_TESTS=OFF

cmake --build cmake-asan-runner --target executor_runner -j2

Run the benign control:

ASAN_OPTIONS=detect_leaks=0:abort_on_error=1 \
  ./cmake-asan-runner/executor_runner \
  --model_path ../hf_upload_conv_bias_pte/benign_conv_bias.pte \
  --method_name forward

Expected benign output:

Model executed successfully
OutputX 0: tensor(sizes=[1, 4, 3], [7., 7., 7., 7., ...])

Run the malformed PTE:

ASAN_OPTIONS=detect_leaks=0:abort_on_error=1:symbolize=1 \
  ./cmake-asan-runner/executor_runner \
  --model_path ../hf_upload_conv_bias_pte/executorch_conv_bias_oob_read_poc.pte \
  --method_name forward

Expected result:

ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 4
torch::executor::native::utils::internal::load_and_convert<float, float>
kernels/portable/cpu/util/dtype_util.h:21
conv2d_impl<float>
kernels/portable/cpu/op_convolution.cpp:137
torch::executor::native::convolution_out
kernels/portable/cpu/op_convolution.cpp:415
executorch::runtime::Method::execute_instruction
runtime/executor/method.cpp:1472
executorch::runtime::Method::execute
runtime/executor/method.cpp:1758

The included asan_trace_executor_runner.txt contains the full trace from the tested run.

Downloads last month
8
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support