Skip to content

BUG: Fix segfault in seterr() on self-referencing object array (gh-32… - #32620

Merged
ngoldbaum merged 5 commits into
numpy:mainfrom
BHUVANSH855:fix-seterr-selfref-segfault
Sep 14, 2026
Merged

ngoldbaum merged 5 commits into
numpy:mainfrom
BHUVANSH855:fix-seterr-selfref-segfault

Conversation

@BHUVANSH855

@BHUVANSH855 BHUVANSH855 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

PR summary

[Say how you found this — e.g. "I was fuzzing my numpy fork with fusil
when this came up."]

numpy.seterr() segfaults when passed a self-referencing object array
instead of raising an error. The cause is in errmodeconverter
(extobj.c), which compares the argument against candidate mode strings
using PyObject_RichCompareBool. For a self-referencing object array this
recurses forever into elementwise comparison, since at every level the
array is being compared against a plain string, not against itself, so
the identity short-circuit never kicks in.

The fix rejects non-string, non-None values before any comparison
happens, instead of trying to bound the recursion.

I also added a Py_EnterRecursiveCall guard to array_richcompare's
tp_richcompare slot as defense-in-depth, matching the pattern from
#8306/#9077. [Mention here if you want: testing showed this guard alone
doesn't fix the crash, since numpy's ufunc dispatch path uses larger
per-frame stack usage than the recursion counter assumes — the
extobj.c type check is what actually fixes it.]

Added two tests in test_errstate.py. Confirmed the existing
test_errstate.py suite (8/8) and the comparison-related tests in
test_multiarray.py (13/13) still pass.

First time contributor introduction

New to numpy. I've contributed to CPython before (PR triager) and built a
few developer tooling projects (docs translation coordination, review
toolkits for CPython/PyPy). Found this bug while fuzzing numpy with fusil.

AI Disclosure

No AI used.

…gh-32609)

Passing a self-referencing object array as the `all` (or `divide`/
`over`/`under`/`invalid`) argument to `numpy.seterr()` caused a
segmentation fault instead of raising an exception.

`errmodeconverter` in extobj.c compared the argument against candidate
mode strings using `PyObject_RichCompareBool`. For a self-referencing
object array this recurses into elementwise comparison machinery
forever, since at every level the array (or a container reachable from
it) is being compared against a string, never against itself, so no
identity short-circuit applies. On platforms with larger per-frame C
stack usage this exhausts the stack before Python's own recursion
tracking can intervene, producing a segfault rather than a
RecursionError.

Fix this at its root by rejecting non-string, non-None values for
these arguments before any comparison happens at all.

Also add a Py_EnterRecursiveCall guard to array_richcompare's
tp_richcompare slot as defense-in-depth for other callers that reach
elementwise object-array comparison with self-referencing data,
mirroring the existing guard for bool(array) self-containment
(numpygh-8306, numpygh-9077). This alone is not sufficient to fix the seterr
crash (confirmed by testing: the C-recursion counter guard doesn't
reliably trip before the physical stack is exhausted, since numpy's
ufunc dispatch path uses larger-than-typical per-frame stack usage),
but is a reasonable additional safeguard.

Closes numpygh-32609
Comment thread numpy/_core/src/multiarray/arrayobject.c Outdated
Comment thread numpy/_core/src/multiarray/arrayobject.c Outdated
Comment thread numpy/_core/src/umath/extobj.c Outdated
Comment thread numpy/_core/tests/test_errstate.py
BHUVANSH855 and others added 2 commits September 15, 2026 01:44
Co-authored-by: Nathan Goldbaum <nathan.goldbaum@gmail.com>
Co-authored-by: Nathan Goldbaum <nathan.goldbaum@gmail.com>
Comment thread numpy/_core/src/multiarray/arrayobject.c Outdated

@ngoldbaum ngoldbaum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Try to keep diffs on PRs as minimal as possible, like this ended up 😄

@ngoldbaum ngoldbaum added the 09 - Backport-Candidate PRs tagged should be backported label Sep 14, 2026
@BHUVANSH855

Copy link
Copy Markdown
Contributor Author

Thanks! Try to keep diffs on PRs as minimal as possible, like this ended up 😄

Thanks to make my first contribution as memorial, will learn a lot from this and try to help team with more valuable fixes.

@ngoldbaum
ngoldbaum merged commit 98105a3 into numpy:main Sep 14, 2026
91 checks passed
@BHUVANSH855
BHUVANSH855 deleted the fix-seterr-selfref-segfault branch September 14, 2026 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

00 - Bug 09 - Backport-Candidate PRs tagged should be backported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants