Skip to content

Fix 32-bit integer overflow in LAPACKE nancheck index arithmetic#5835

Merged
martin-frbg merged 1 commit into
OpenMathLib:developfrom
changangela:fix-lapacke-nancheck-overflow
Jun 12, 2026
Merged

Fix 32-bit integer overflow in LAPACKE nancheck index arithmetic#5835
martin-frbg merged 1 commit into
OpenMathLib:developfrom
changangela:fix-lapacke-nancheck-overflow

Conversation

@changangela

@changangela changangela commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

The LAPACKE NaN checks compute array offsets in 32-bit lapack_int, which overflows for large matrices. Found while running Cholesky on a 47000x47000 matrix: LAPACKE_dpotrf with n = lda >= 46341 crashes in LAPACKE_dtr_nancheck before the factorization even runs, because j*lda wraps negative. Same family of overflow as scipy/scipy#20229.

The ge/gb/tp/tf helpers already cast to size_t, so this applies the same fix to the ones that were missed:

  • ?tr_nancheck: cast a[i+j*lda] to size_t (covers the po/sy/he checks, i.e. potrf)
  • ?_nancheck (vector): the n*inc loop bound overflowed; iterate by count and index with size_t
  • ?sp/?pp/?pf/?hp/?tp/?tf: compute the packed length n*(n+1)/2 in size_t
  • ?tz_nancheck: widen the part offsets to int64_t

Tested with UBSan at n = 47000: the old code overflows and segfaults (tr, tz) or silently returns "no NaN" on input that has one (vector, packed); the fixed code detects a NaN planted at the far end of the scanned region in all cases. Old and new code give identical results on an exhaustive sweep of small sizes (all layouts/uplo/diag/shapes, NaN at every position).

Reference-LAPACK master has the same bug in these files; I can submit the fix there as well.

@changangela changangela marked this pull request as draft June 12, 2026 03:40
The optional NaN checks performed by LAPACKE front-ends computed array
offsets and lengths in 32-bit lapack_int arithmetic, which overflows for
large matrices (e.g. LAPACKE_dpotrf with n = lda >= 46341 overflows
j*lda in LAPACKE_dtr_nancheck, leading to out-of-bounds reads and
crashes). Several nancheck helpers (ge, gb, tp, tf) already cast to
size_t; this applies the same treatment to the ones that were missed:

- ?tr_nancheck: cast a[i+j*lda] index to size_t (also covers po/sy/he
  checks, i.e. the POTRF/Cholesky path)
- ?_nancheck (vector): iterate by element count instead of n*inc, with
  size_t indexing
- ?sp/?pp/?pf/?hp/?tp/?tf_nancheck: compute n*(n+1)/2 length in size_t
- ?tz_nancheck: widen the part offsets to int64_t (keeping the -1
  sentinel) and compute them with a widening cast

Verified with UBSan: LAPACKE_str_nancheck at n = lda = 47000 previously
reported signed integer overflow and crashed with SEGV at -O0; it now
passes and still detects the NaN. Old and new code produce identical
results across 1907 enumerated small-size cases (all layouts, uplo,
diag, shapes and NaN positions for tr/tz/vector/packed variants).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@changangela changangela force-pushed the fix-lapacke-nancheck-overflow branch from 7f7585d to ede136e Compare June 12, 2026 03:42
@changangela changangela marked this pull request as ready for review June 12, 2026 03:55
@martin-frbg

Copy link
Copy Markdown
Collaborator

Thank you - and yes please submit this fix to Reference-LAPACK as well, we're only copying LAPACKE and (most of) LAPACK from there

@changangela

Copy link
Copy Markdown
Contributor Author

Thank you - and yes please submit this fix to Reference-LAPACK as well, we're only copying LAPACKE and (most of) LAPACK from there

sounds good, here it is: Reference-LAPACK/lapack#1294

@martin-frbg martin-frbg added this to the 0.3.34 milestone Jun 12, 2026
@martin-frbg martin-frbg merged commit 7aa79fb into OpenMathLib:develop Jun 12, 2026
99 of 100 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants