[Python] `call_tabular_function()` segfaults for some wrong typed `func_registry` values
- Dominant language
- C++
- Stars
- 17.1k
- Forks
- 4.3k
- Avg merge
- 3d 13h
- Merged PRs (30d)
- 88
Description
### Describe the bug, including details regarding any error messages, version, and platform.
### Summary
The behavior of `pyarrow.compute.call_tabular_function()` depends on the value supplied as a wrong typed `func_registry`.
Some values, including `0.0`, `1`, and `-1`, terminate the interpreter with `SIGSEGV`.
Most other tested wrong type values do not crash and instead reach the normal missing function `ArrowKeyError` path.
I think all non-FunctionRegistry values should be handled consistently without terminating the process, preferably by raising `TypeError`.
I found this while fuzzing Python C extension modules.
### Versions
PyArrow 25.0.0, CPython 3.12.3, Ubuntu 24.04 x86_64, glibc 2.39.
### Reproducer
```python
import pyarrow.compute as pc
pc.call_tabular_function("", None, 0.0)
```
```console
Segmentation fault (core dumped)
```
### Input validation behavior
I kept the function name and `args=None` unchanged and independently varied only `func_registry` on the same binary wheel.
| Result | Tested `func_registry` values |
| --- | --- |
| SIGSEGV | `True`, `1`, `-1`, `0.0`, `1j`, `dict` |
| `ArrowKeyError` from the missing function name | `None`, `False`, `0`, `inf`, `nan`, `0j`, `str`, `bytes`, `bytearray`, `list`, `tuple`, `set`,`object()` |
### ASan/UBSan result
An earlier instrumented variant using the same wrong-typed registry path reported a misaligned member call in `CallTabularFunction()`:
```text
pyarrow/src/arrow/python/udf.cc:655:3: runtime error:
member call on misaligned address 0x00010c3298eb
for type 'arrow::compute::FunctionRegistry', which requires 8 byte alignment
#0 arrow::py::CallTabularFunction(...)
pyarrow/src/arrow/python/udf.cc:655:3
#1 pyarrow._compute.call_tabular_function(...)
build/_compute.cpp:70892:92
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior
pyarrow/src/arrow/python/udf.cc:655:3
```
The sanitizer process exits with code 1 at the first UBSan diagnostic.
ASan does not emit a separate diagnostic when UBSan is configured to stop at that first error.
### Component(s)
Python
Contributor guide
Research direction
Start at pyarrow/src/arrow/python/udf.cc:655 in CallTabularFunction() and reproduce the crash with the provided Python call using the listed wrong-typed func_registry values. Run the reproducer under UBSan or the affected wheel and verify that non-FunctionRegistry inputs consistently raise TypeError without terminating the interpreter.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100