pytorch / pytorch/pytorch

[Quantized CPU] _adaptive_avg_pool3d reads outside a short output_size list

Open
#194,804 1 comment 0 reactions 0 assignees View on GitHub
bot-triaged oncall: quantization
Dominant language
Python
Stars
103k
Forks
29.5k
PR merge metrics
PR metrics pending

Description

# Title

`[Quantized CPU] _adaptive_avg_pool3d reads outside a short output_size list`

### Describe the bug

The quantized CPU implementation of `aten::_adaptive_avg_pool3d` accepts an empty or otherwise short `output_size`. It appends the supplied values to a C++ vector and then indexes the final three elements unconditionally.

This was found during an unpublished fuzzing project and then reduced to the
standalone call below.

### Reproduction

```python
import torch

torch.set_num_threads(1)
source = torch.arange(8, dtype=torch.float32).reshape(1, 1, 2, 2, 2)
input_tensor = torch.quantize_per_tensor(
source, scale=0.1, zero_point=0, dtype=torch.qint8
)

torch.ops.aten._adaptive_avg_pool3d(input_tensor, [])
```

### Error message

Running the reproduction above on an ASan-enabled CPU build reports a
8-byte heap out-of-bounds read. The report is verbatim except that absolute build-root
prefixes were replaced with ``, ``,
``, ``, and ``.

```text
=================================================================
==1600==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x604000563108 at pc 0x7f14867c0016 bp 0x7ffe93abeed0 sp 0x7ffe93abeec8
READ of size 8 at 0x604000563108 thread T0
#0 0x7f14867c0015 in at::Tensor at::native::(anonymous namespace)::_adaptive_avg_pool<3, c10::qint8>(at::Tensor const&, c10::ArrayRef, at::Tensor&) /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:185:40
#1 0x7f14867bf8fd in at::Tensor at::native::(anonymous namespace)::q_adaptive_avg_pool3d(at::Tensor&, at::Tensor const&, c10::ArrayRef) /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:255:10
#2 0x7f14867bf158 in at::native::adaptive_avg_pool3d_out_quantized_cpu(at::Tensor const&, c10::ArrayRef, at::Tensor&)::$_0::operator()() const::'lambda'()::operator()() const /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:329:3
#3 0x7f14867af0a7 in at::native::adaptive_avg_pool3d_out_quantized_cpu(at::Tensor const&, c10::ArrayRef, at::Tensor&)::$_0::operator()() const /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:329:3
#4 0x7f14867aea7b in at::native::adaptive_avg_pool3d_out_quantized_cpu(at::Tensor const&, c10::ArrayRef, at::Tensor&) /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:329:3
#5 0x7f14867afae0 in at::native::adaptive_avg_pool3d_quantized_cpu(at::Tensor const&, c10::ArrayRef) /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:340:10
#6 0x7f148e461e73 in at::(anonymous namespace)::(anonymous namespace)::wrapper_QuantizedCPU___adaptive_avg_pool3d(at::Tensor const&, c10::ArrayRef) /build/aten/src/ATen/RegisterQuantizedCPU_0.cpp:2327:10
#7 0x7f148e532182 in c10::impl::detail::WrapFunctionIntoFunctor_), &at::(anonymous namespace)::(anonymous namespace)::wrapper_QuantizedCPU___adaptive_avg_pool3d(at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>::operator()(at::Tensor const&, c10::ArrayRef) /aten/src/ATen/core/boxing/impl/WrapFunctionIntoFunctor.h:17:12
#8 0x7f148e532182 in c10::impl::wrap_kernel_functor_unboxed_), &at::(anonymous namespace)::(anonymous namespace)::wrapper_QuantizedCPU___adaptive_avg_pool3d(at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>, at::Tensor (at::Tensor const&, c10::ArrayRef)>::call(c10::OperatorKernel*, c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) /aten/src/ATen/core/boxing/impl/make_boxed_from_unboxed_functor.h:577:12
#9 0x7f148778ad1f in at::Tensor c10::callUnboxedKernelFunction>(void*, c10::OperatorKernel*, c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef&&) /aten/src/ATen/core/boxing/KernelFunction_impl.h:103:10
#10 0x7f148778be61 in at::Tensor c10::KernelFunction::call>(c10::OperatorHandle const&, c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) const /aten/src/ATen/core/boxing/KernelFunction_impl.h:152:14
#11 0x7f148778be61 in at::Tensor c10::Dispatcher::redispatch>(c10::TypedOperatorHandle)> const&, c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) const /aten/src/ATen/core/dispatch/Dispatcher.h:847:26
#12 0x7f14893afcec in c10::TypedOperatorHandle)>::redispatch(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) const /aten/src/ATen/core/dispatch/Dispatcher.h:622:41
#13 0x7f14893afcec in at::_ops::_adaptive_avg_pool3d::redispatch(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) /build/aten/src/ATen/Operators_3.cpp:8056:15
#14 0x7f1495a3eed5 in at::redispatch::_adaptive_avg_pool3d_symint(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) /build/aten/src/ATen/RedispatchFunctions.h:13727:16
#15 0x7f1495773656 in torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)::$_0::operator()() const /torch/csrc/autograd/generated/VariableType_3.cpp:391:12
#16 0x7f149577236b in torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) /torch/csrc/autograd/generated/VariableType_3.cpp:389:15
#17 0x7f1495774211 in c10::impl::detail::WrapFunctionIntoFunctor_), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>::operator()(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) /aten/src/ATen/core/boxing/impl/WrapFunctionIntoFunctor.h:17:12
#18 0x7f1495774211 in c10::impl::wrap_kernel_functor_unboxed_), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>, at::Tensor (c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>::call(c10::OperatorKernel*, c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) /aten/src/ATen/core/boxing/impl/make_boxed_from_unboxed_functor.h:610:12
#19 0x7f1495774a4a in std::decay), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>>::type::return_type>::type c10::impl::call_functor_with_args_from_stack_), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>, false, 0ul, 1ul, at::Tensor const&, c10::ArrayRef>(c10::OperatorKernel*, c10::DispatchKeySet, std::vector>*, std::integer_sequence, c10::guts::typelist::typelist>*) /aten/src/ATen/core/boxing/impl/make_boxed_from_unboxed_functor.h:641:10
#20 0x7f1495774726 in std::decay), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>>::type::return_type>::type c10::impl::call_functor_with_args_from_stack), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>, false>(c10::OperatorKernel*, c10::DispatchKeySet, std::vector>*) /aten/src/ATen/core/boxing/impl/make_boxed_from_unboxed_functor.h:665:10
#21 0x7f1495774449 in c10::impl::make_boxed_from_unboxed_functor), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>, false>::call(c10::OperatorKernel*, c10::OperatorHandle const&, c10::DispatchKeySet, std::vector>*) /aten/src/ATen/core/boxing/impl/make_boxed_from_unboxed_functor.h:780:28
#22 0x7f1483836ce0 in c10::BoxedKernel::callBoxed(c10::OperatorHandle const&, c10::DispatchKeySet, std::vector>*) const /aten/src/ATen/core/boxing/BoxedKernel_impl.h:48:3
#23 0x7f148383603e in c10::KernelFunction::callBoxed(c10::OperatorHandle const&, c10::DispatchKeySet, std::vector>*) const /aten/src/ATen/core/boxing/KernelFunction_impl.h:91:22
#24 0x7f14839280af in c10::Dispatcher::callBoxed(c10::OperatorHandle const&, std::vector>*) const /aten/src/ATen/core/dispatch/Dispatcher.h:892:10
#25 0x7f1483925fc1 in c10::OperatorHandle::callBoxed(std::vector>*) const /aten/src/ATen/core/dispatch/Dispatcher.h:539:34
#26 0x7f149a1ff8cc in c10::OperatorHandle::callBoxed(std::vector>&) const /aten/src/ATen/core/dispatch/Dispatcher.h:543:5
#27 0x7f149c69c5bc in torch::jit::(anonymous namespace)::createOperatorFromC10(c10::OperatorHandle const&)::$_0::operator()(std::vector>&) const /torch/csrc/jit/runtime/register_c10_ops.cpp:10:47
#28 0x7f149c69c58c in void std::__invoke_impl>&>(std::__invoke_other, torch::jit::(anonymous namespace)::createOperatorFromC10(c10::OperatorHandle const&)::$_0&, std::vector>&) /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:61:14
#29 0x7f149c69c51c in std::enable_if>&>, void>::type std::__invoke_r>&>(torch::jit::(anonymous namespace)::createOperatorFromC10(c10::OperatorHandle const&)::$_0&, std::vector>&) /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/invoke.h:111:2
#30 0x7f149c69c384 in std::_Function_handler>&), torch::jit::(anonymous namespace)::createOperatorFromC10(c10::OperatorHandle const&)::$_0>::_M_invoke(std::_Any_data const&, std::vector>&) /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:290:9
#31 0x7f14b180e54a in std::function>&)>::operator()(std::vector>&) const /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_function.h:591:9
#32 0x7f14b1c6b03c in torch::jit::Operation::operator()(std::vector>&) /aten/src/ATen/core/stack.h:43:5
#33 0x7f14b1c5190a in torch::jit::invokeOperatorFromPython(c10::ArrayRef>, pybind11::args const&, pybind11::kwargs const&, std::optional) /torch/csrc/jit/python/pybind_utils.cpp:897:7
#34 0x7f14b1c539ab in torch::jit::_get_operation_for_overload_or_packet(c10::ArrayRef>, c10::Symbol, pybind11::args const&, pybind11::kwargs const&, bool, std::optional) /torch/csrc/jit/python/pybind_utils.cpp:1009:9
#35 0x7f14b1762aa9 in torch::jit::initJITBindings(_object*)::$_222::operator()(std::__cxx11::basic_string, std::allocator> const&, std::__cxx11::basic_string, std::allocator> const&) const::'lambda'(pybind11::args const&, pybind11::kwargs const&)::operator()(pybind11::args const&, pybind11::kwargs const&) const /torch/csrc/jit/python/init.cpp:1742:28
#36 0x7f14b1762758 in pybind11::object pybind11::detail::argument_loader::call_impl, std::allocator> const&, std::__cxx11::basic_string, std::allocator> const&) const::'lambda'(pybind11::args const&, pybind11::kwargs const&)&, 0ul, 1ul, pybind11::detail::void_type>(torch::jit::initJITBindings(_object*)::$_222::operator()(std::__cxx11::basic_string, std::allocator> const&, std::__cxx11::basic_string, std::allocator> const&) const::'lambda'(pybind11::args const&, pybind11::kwargs const&)&, std::integer_sequence, pybind11::detail::void_type&&) && /cmake/../third_party/pybind11/include/pybind11/cast.h:2195:16
#37 0x7f14b1762693 in std::enable_if::value, pybind11::object>::type pybind11::detail::argument_loader::call, std::allocator> const&, std::__cxx11::basic_string, std::allocator> const&) const::'lambda'(pybind11::args const&, pybind11::kwargs const&)&>(torch::jit::initJITBindings(_object*)::$_222::operator()(std::__cxx11::basic_string, std::allocator> const&, std::__cxx11::basic_string, std::allocator> const&) const::'lambda'(pybind11::args const&, pybind11::kwargs const&)&) && /cmake/../third_party/pybind11/include/pybind11/cast.h:2157:42
#38 0x7f14b1762299 in void pybind11::cpp_function::initialize, std::allocator> const&, std::__cxx11::basic_string, std::allocator> const&) const::'lambda'(pybind11::args const&, pybind11::kwargs const&), pybind11::object, pybind11::args const&, pybind11::kwargs const&>(torch::jit::initJITBindings(_object*)::$_222::operator()(std::__cxx11::basic_string, std::allocator> const&, std::__cxx11::basic_string, std::allocator> const&) const::'lambda'(pybind11::args const&, pybind11::kwargs const&)&&, pybind11::object (*)(pybind11::args const&, pybind11::kwargs const&))::'lambda'(pybind11::detail::function_call&)::operator()(pybind11::detail::function_call&) const /cmake/../third_party/pybind11/include/pybind11/pybind11.h:570:56
#39 0x7f14b1761cab in void pybind11::cpp_function::initialize, std::allocator> const&, std::__cxx11::basic_string, std::allocator> const&) const::'lambda'(pybind11::args const&, pybind11::kwargs const&), pybind11::object, pybind11::args const&, pybind11::kwargs const&>(torch::jit::initJITBindings(_object*)::$_222::operator()(std::__cxx11::basic_string, std::allocator> const&, std::__cxx11::basic_string, std::allocator> const&) const::'lambda'(pybind11::args const&, pybind11::kwargs const&)&&, pybind11::object (*)(pybind11::args const&, pybind11::kwargs const&))::'lambda'(pybind11::detail::function_call&)::__invoke(pybind11::detail::function_call&) /cmake/../third_party/pybind11/include/pybind11/pybind11.h:540:21
#40 0x7f14af1e8799 in pybind11::cpp_function::dispatcher(_object*, _object* const*, unsigned long, _object*) /cmake/../third_party/pybind11/include/pybind11/pybind11.h:1209:30
#41 0x571e6088f7fe in cfunction_vectorcall_FASTCALL_KEYWORDS /usr/local/src/conda/python-3.11.15/Objects/methodobject.c:443:24
#42 0x571e6088b792 in do_call_core /usr/local/src/conda/python-3.11.15/Python/ceval.c:7321:9
#43 0x571e6088b792 in _PyEval_EvalFrameDefault /usr/local/src/conda/python-3.11.15/Python/ceval.c:5376:22
#44 0x571e608a93d4 in _PyEval_EvalFrame /usr/local/src/conda/python-3.11.15/Include/internal/pycore_ceval.h:73:16
#45 0x571e608a93d4 in _PyEval_Vector /usr/local/src/conda/python-3.11.15/Python/ceval.c:6434:24
#46 0x571e608a93d4 in _PyFunction_Vectorcall /usr/local/src/conda/python-3.11.15/Objects/call.c:393:16
#47 0x571e6087a154 in _PyObject_FastCallDictTstate /usr/local/src/conda/python-3.11.15/Objects/call.c:141:15
#48 0x571e608b1436 in _PyObject_Call_Prepend /usr/local/src/conda/python-3.11.15/Objects/call.c:482:24
#49 0x571e60984896 in slot_tp_call /usr/local/src/conda/python-3.11.15/Objects/typeobject.c:7624
#50 0x571e608753fa in _PyObject_MakeTpCall /usr/local/src/conda/python-3.11.15/Objects/call.c:214:18
#51 0x571e60883754 in _PyEval_EvalFrameDefault /usr/local/src/conda/python-3.11.15/Python/ceval.c:4769:23
#52 0x571e6093fd54 in _PyEval_EvalFrame /usr/local/src/conda/python-3.11.15/Include/internal/pycore_ceval.h:73:16
#53 0x571e6093fd54 in _PyEval_Vector /usr/local/src/conda/python-3.11.15/Python/ceval.c:6434:24
#54 0x571e6093f49c in PyEval_EvalCode /usr/local/src/conda/python-3.11.15/Python/ceval.c:1148:21
#55 0x571e6095688c in builtin_exec_impl /usr/local/src/conda/python-3.11.15/Python/bltinmodule.c:1077:17
#56 0x571e6095688c in builtin_exec /usr/local/src/conda/python-3.11.15/Python/clinic/bltinmodule.c.h:465:20
#57 0x571e6088f7fe in cfunction_vectorcall_FASTCALL_KEYWORDS /usr/local/src/conda/python-3.11.15/Objects/methodobject.c:443:24
#58 0x571e6088f6eb in _PyObject_VectorcallTstate /usr/local/src/conda/python-3.11.15/Include/internal/pycore_call.h:92:11
#59 0x571e6088f6eb in PyObject_Vectorcall /usr/local/src/conda/python-3.11.15/Objects/call.c:299:12
#60 0x571e60883754 in _PyEval_EvalFrameDefault /usr/local/src/conda/python-3.11.15/Python/ceval.c:4769:23
#61 0x571e6093fd54 in _PyEval_EvalFrame /usr/local/src/conda/python-3.11.15/Include/internal/pycore_ceval.h:73:16
#62 0x571e6093fd54 in _PyEval_Vector /usr/local/src/conda/python-3.11.15/Python/ceval.c:6434:24
#63 0x571e6093f49c in PyEval_EvalCode /usr/local/src/conda/python-3.11.15/Python/ceval.c:1148:21
#64 0x571e6095cf49 in run_eval_code_obj /usr/local/src/conda/python-3.11.15/Python/pythonrun.c:1741:9
#65 0x571e60958c42 in run_mod /usr/local/src/conda/python-3.11.15/Python/pythonrun.c:1762:19
#66 0x571e6096e4ff in pyrun_file /usr/local/src/conda/python-3.11.15/Python/pythonrun.c:1657:15
#67 0x571e6096de89 in _PyRun_SimpleFileObject /usr/local/src/conda/python-3.11.15/Python/pythonrun.c:440:13
#68 0x571e6096dc63 in _PyRun_AnyFileObject /usr/local/src/conda/python-3.11.15/Python/pythonrun.c:79:15
#69 0x571e60967fa0 in pymain_run_file_obj /usr/local/src/conda/python-3.11.15/Modules/main.c:360:15
#70 0x571e60967fa0 in pymain_run_file /usr/local/src/conda/python-3.11.15/Modules/main.c:379:15
#71 0x571e60967fa0 in pymain_run_python /usr/local/src/conda/python-3.11.15/Modules/main.c:605:21
#72 0x571e60967fa0 in Py_RunMain /usr/local/src/conda/python-3.11.15/Modules/main.c:684:5
#73 0x571e6092f366 in Py_BytesMain /usr/local/src/conda/python-3.11.15/Modules/main.c:738:12
#74 0x7f14b77e0d8f (/usr/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)
#75 0x7f14b77e0e3f in __libc_start_main (/usr/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: 490fef8403240c91833978d494d39e537409b92e)
#76 0x571e6092f1f8 in _start (/bin/python3.11+0x2931f8)

0x604000563108 is located 8 bytes before 40-byte region [0x604000563110,0x604000563138)
allocated by thread T0 here:
#0 0x7f14b7bcc98d in operator new(unsigned long) /compiler-rt/lib/asan/asan_new_delete.cpp:95:3
#1 0x7f14838a8f89 in std::__new_allocator::allocate(unsigned long, void const*) /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/new_allocator.h:137:27
#2 0x7f14838a8f10 in std::allocator::allocate(unsigned long) /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/allocator.h:188:32
#3 0x7f14838a8f10 in std::allocator_traits>::allocate(std::allocator&, unsigned long) /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/alloc_traits.h:464:20
#4 0x7f14838a8ebf in std::_Vector_base>::_M_allocate(unsigned long) /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_vector.h:378:20
#5 0x7f1483931f25 in std::vector>::reserve(unsigned long) /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/vector.tcc:79:22
#6 0x7f14867c2000 in std::vector> at::native::(anonymous namespace)::get_output_shape<3l>(at::Tensor const&, c10::ArrayRef) /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:161:16
#7 0x7f14867bfe4b in at::Tensor at::native::(anonymous namespace)::_adaptive_avg_pool<3, c10::qint8>(at::Tensor const&, c10::ArrayRef, at::Tensor&) /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:178:29
#8 0x7f14867bf8fd in at::Tensor at::native::(anonymous namespace)::q_adaptive_avg_pool3d(at::Tensor&, at::Tensor const&, c10::ArrayRef) /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:255:10
#9 0x7f14867bf158 in at::native::adaptive_avg_pool3d_out_quantized_cpu(at::Tensor const&, c10::ArrayRef, at::Tensor&)::$_0::operator()() const::'lambda'()::operator()() const /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:329:3
#10 0x7f14867af0a7 in at::native::adaptive_avg_pool3d_out_quantized_cpu(at::Tensor const&, c10::ArrayRef, at::Tensor&)::$_0::operator()() const /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:329:3
#11 0x7f14867aea7b in at::native::adaptive_avg_pool3d_out_quantized_cpu(at::Tensor const&, c10::ArrayRef, at::Tensor&) /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:329:3
#12 0x7f14867afae0 in at::native::adaptive_avg_pool3d_quantized_cpu(at::Tensor const&, c10::ArrayRef) /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:340:10
#13 0x7f148e461e73 in at::(anonymous namespace)::(anonymous namespace)::wrapper_QuantizedCPU___adaptive_avg_pool3d(at::Tensor const&, c10::ArrayRef) /build/aten/src/ATen/RegisterQuantizedCPU_0.cpp:2327:10
#14 0x7f148e532182 in c10::impl::detail::WrapFunctionIntoFunctor_), &at::(anonymous namespace)::(anonymous namespace)::wrapper_QuantizedCPU___adaptive_avg_pool3d(at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>::operator()(at::Tensor const&, c10::ArrayRef) /aten/src/ATen/core/boxing/impl/WrapFunctionIntoFunctor.h:17:12
#15 0x7f148e532182 in c10::impl::wrap_kernel_functor_unboxed_), &at::(anonymous namespace)::(anonymous namespace)::wrapper_QuantizedCPU___adaptive_avg_pool3d(at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>, at::Tensor (at::Tensor const&, c10::ArrayRef)>::call(c10::OperatorKernel*, c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) /aten/src/ATen/core/boxing/impl/make_boxed_from_unboxed_functor.h:577:12
#16 0x7f148778ad1f in at::Tensor c10::callUnboxedKernelFunction>(void*, c10::OperatorKernel*, c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef&&) /aten/src/ATen/core/boxing/KernelFunction_impl.h:103:10
#17 0x7f148778be61 in at::Tensor c10::KernelFunction::call>(c10::OperatorHandle const&, c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) const /aten/src/ATen/core/boxing/KernelFunction_impl.h:152:14
#18 0x7f148778be61 in at::Tensor c10::Dispatcher::redispatch>(c10::TypedOperatorHandle)> const&, c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) const /aten/src/ATen/core/dispatch/Dispatcher.h:847:26
#19 0x7f14893afcec in c10::TypedOperatorHandle)>::redispatch(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) const /aten/src/ATen/core/dispatch/Dispatcher.h:622:41
#20 0x7f14893afcec in at::_ops::_adaptive_avg_pool3d::redispatch(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) /build/aten/src/ATen/Operators_3.cpp:8056:15
#21 0x7f1495a3eed5 in at::redispatch::_adaptive_avg_pool3d_symint(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) /build/aten/src/ATen/RedispatchFunctions.h:13727:16
#22 0x7f1495773656 in torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)::$_0::operator()() const /torch/csrc/autograd/generated/VariableType_3.cpp:391:12
#23 0x7f149577236b in torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) /torch/csrc/autograd/generated/VariableType_3.cpp:389:15
#24 0x7f1495774211 in c10::impl::detail::WrapFunctionIntoFunctor_), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>::operator()(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) /aten/src/ATen/core/boxing/impl/WrapFunctionIntoFunctor.h:17:12
#25 0x7f1495774211 in c10::impl::wrap_kernel_functor_unboxed_), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>, at::Tensor (c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>::call(c10::OperatorKernel*, c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef) /aten/src/ATen/core/boxing/impl/make_boxed_from_unboxed_functor.h:610:12
#26 0x7f1495774a4a in std::decay), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>>::type::return_type>::type c10::impl::call_functor_with_args_from_stack_), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>, false, 0ul, 1ul, at::Tensor const&, c10::ArrayRef>(c10::OperatorKernel*, c10::DispatchKeySet, std::vector>*, std::integer_sequence, c10::guts::typelist::typelist>*) /aten/src/ATen/core/boxing/impl/make_boxed_from_unboxed_functor.h:641:10
#27 0x7f1495774726 in std::decay), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>>::type::return_type>::type c10::impl::call_functor_with_args_from_stack), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>, false>(c10::OperatorKernel*, c10::DispatchKeySet, std::vector>*) /aten/src/ATen/core/boxing/impl/make_boxed_from_unboxed_functor.h:665:10
#28 0x7f1495774449 in c10::impl::make_boxed_from_unboxed_functor), &torch::autograd::VariableType::(anonymous namespace)::_adaptive_avg_pool3d(c10::DispatchKeySet, at::Tensor const&, c10::ArrayRef)>, at::Tensor, c10::guts::typelist::typelist>>, false>::call(c10::OperatorKernel*, c10::OperatorHandle const&, c10::DispatchKeySet, std::vector>*) /aten/src/ATen/core/boxing/impl/make_boxed_from_unboxed_functor.h:780:28
#29 0x7f1483836ce0 in c10::BoxedKernel::callBoxed(c10::OperatorHandle const&, c10::DispatchKeySet, std::vector>*) const /aten/src/ATen/core/boxing/BoxedKernel_impl.h:48:3
#30 0x7f148383603e in c10::KernelFunction::callBoxed(c10::OperatorHandle const&, c10::DispatchKeySet, std::vector>*) const /aten/src/ATen/core/boxing/KernelFunction_impl.h:91:22
#31 0x7f14839280af in c10::Dispatcher::callBoxed(c10::OperatorHandle const&, std::vector>*) const /aten/src/ATen/core/dispatch/Dispatcher.h:892:10
#32 0x7f1483925fc1 in c10::OperatorHandle::callBoxed(std::vector>*) const /aten/src/ATen/core/dispatch/Dispatcher.h:539:34
#33 0x7f149a1ff8cc in c10::OperatorHandle::callBoxed(std::vector>&) const /aten/src/ATen/core/dispatch/Dispatcher.h:543:5
#34 0x7f149c69c5bc in torch::jit::(anonymous namespace)::createOperatorFromC10(c10::OperatorHandle const&)::$_0::operator()(std::vector>&) const /torch/csrc/jit/runtime/register_c10_ops.cpp:10:47

SUMMARY: AddressSanitizer: heap-buffer-overflow /aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp:185:40 in at::Tensor at::native::(anonymous namespace)::_adaptive_avg_pool<3, c10::qint8>(at::Tensor const&, c10::ArrayRef, at::Tensor&)
Shadow bytes around the buggy address:
0x604000562e80: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fd
0x604000562f00: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fd
0x604000562f80: fa fa fd fd fd fd fd fa fa fa 00 00 00 00 00 fa
0x604000563000: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
0x604000563080: fa fa fd fd fd fd fd fa fa fa 00 00 00 00 00 fa
=>0x604000563100: fa[fa]00 00 00 00 00 fa fa fa fa fa fa fa fa fa
0x604000563180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x604000563200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x604000563280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x604000563300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x604000563380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==1600==ABORTING
```

### Current release behavior

On the official `torch 2.13.0+cpu` wheel, The empty `output_size` is not rejected; the process terminates with signal 11 (exit status 139). The matched three-element control returns normally.

### Expected behavior

The quantized implementation should require exactly three output-size values before indexing its metadata vector.

### JIT exposure

On the official `torch 2.13.0+cpu` wheel, `aten::_adaptive_avg_pool3d` is present in the
JIT operator registry, compiles into TorchScript IR, and remains in the graph
after `torch.jit.save` and `torch.jit.load`.

In serialized TorchScript IR, the `SymInt[3]` schema argument is represented as a general `int[]`, so the fixed-length annotation does not block an empty list.

Marking an operator as private or internal is not an effective safety boundary
while it remains directly invocable through the JIT operator registry and
serialized graphs. This exposes an unchecked native implementation outside its
intended trusted call paths and turns missing validation into a native
memory-safety surface. If direct invocation is unsupported, please consider
removing the operator from the JIT domain; otherwise, validate inputs at the
exposed boundary.

### Additional context

The out-of-bounds read occurs while processing the C++ `output_shape` vector, before output tensor allocation.

The first native failure is in `aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp`. This report concerns
a direct single-operator memory-safety failure and does not require a malformed
tensor produced by another operator.

### Versions

```text
PyTorch version: 2.13.0a0+gitcf30153
Git revision: cf30153c4c131c8164ee7798e5022d810682e2cb
Is debug build: True
CUDA used to build PyTorch: None
ROCM used to build PyTorch: N/A

OS: Linux (x86_64)
Libc version: glibc-2.35
Python version: 3.11.15 (64-bit runtime)
Is CUDA available: False
CUDA runtime version: No CUDA

Build instrumentation: AddressSanitizer
[pip3] torch==2.13.0a0+gitcf30153
```

cc @jianyuh @raghuramank100 @jamesr66a @vkuzo @jgong5 @Xia-Weiwen @leslie-fang-intel

Contributor guide

Open the contributing guide

Research direction

Start in aten/src/ATen/native/quantized/cpu/AdaptiveAveragePooling.cpp, especially the lines identified in the ASan trace: 185, 255, and 329-340. Run the supplied Python reproduction on an ASan-enabled CPU build, then verify that empty and short output_size inputs no longer produce an out-of-bounds read and that the affected behavior is covered by a regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
backend, machine-learning
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.