Skip to content

Commit 7f7585d

Browse files
changangelaclaude
andcommitted
Fix 32-bit integer overflow in LAPACKE nancheck index arithmetic
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: compute triangular/rectangular part offsets in size_t, replacing the -1 sentinel with an explicit flag 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>
1 parent a033631 commit 7f7585d

34 files changed

Lines changed: 86 additions & 66 deletions

lapack-netlib/LAPACKE/utils/lapacke_c_nancheck.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ lapack_logical LAPACKE_c_nancheck( lapack_int n,
4242
if( incx == 0 ) return (lapack_logical) LAPACK_CISNAN( x[0] );
4343
inc = ( incx > 0 ) ? incx : -incx ;
4444

45-
for( i = 0; i < n*inc; i+=inc ) {
46-
if( LAPACK_CISNAN( x[i] ) )
45+
for( i = 0; i < n; i++ ) {
46+
if( LAPACK_CISNAN( x[(size_t)i*inc] ) )
4747
return (lapack_logical) 1;
4848
}
4949
return (lapack_logical) 0;

lapack-netlib/LAPACKE/utils/lapacke_chp_nancheck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@
3939
lapack_logical LAPACKE_chp_nancheck( lapack_int n,
4040
const lapack_complex_float *ap )
4141
{
42-
lapack_int len = n*(n+1)/2;
42+
lapack_int len = (lapack_int)(((size_t)n*(n+1))/2);
4343
return LAPACKE_c_nancheck( len, ap, 1 );
4444
}

lapack-netlib/LAPACKE/utils/lapacke_cpf_nancheck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,6 @@
4040
lapack_logical LAPACKE_cpf_nancheck( lapack_int n,
4141
const lapack_complex_float *a )
4242
{
43-
lapack_int len = n*(n+1)/2;
43+
lapack_int len = (lapack_int)(((size_t)n*(n+1))/2);
4444
return LAPACKE_c_nancheck( len, a, 1 );
4545
}

lapack-netlib/LAPACKE/utils/lapacke_cpp_nancheck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@
3939
lapack_logical LAPACKE_cpp_nancheck( lapack_int n,
4040
const lapack_complex_float *ap )
4141
{
42-
lapack_int len = n*(n+1)/2;
42+
lapack_int len = (lapack_int)(((size_t)n*(n+1))/2);
4343
return LAPACKE_c_nancheck( len, ap, 1 );
4444
}

lapack-netlib/LAPACKE/utils/lapacke_csp_nancheck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@
3939
lapack_logical LAPACKE_csp_nancheck( lapack_int n,
4040
const lapack_complex_float *ap )
4141
{
42-
lapack_int len = n*(n+1)/2;
42+
lapack_int len = (lapack_int)(((size_t)n*(n+1))/2);
4343
return LAPACKE_c_nancheck( len, ap, 1 );
4444
}

lapack-netlib/LAPACKE/utils/lapacke_ctf_nancheck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ lapack_logical LAPACKE_ctf_nancheck( int matrix_layout, char transr,
150150
}
151151
} else {
152152
/* Non-unit case - just check whole array for NaNs. */
153-
len = n*(n+1)/2;
153+
len = (lapack_int)(((size_t)n*(n+1))/2);
154154
return LAPACKE_cge_nancheck( LAPACK_COL_MAJOR, len, 1, a, len );
155155
}
156156
}

lapack-netlib/LAPACKE/utils/lapacke_ctp_nancheck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ lapack_logical LAPACKE_ctp_nancheck( int matrix_layout, char uplo, char diag,
7676
return (lapack_logical) 0;
7777
} else {
7878
/* Non-unit case - just check whole array for NaNs. */
79-
len = n*(n+1)/2;
79+
len = (lapack_int)(((size_t)n*(n+1))/2);
8080
return LAPACKE_c_nancheck( len, ap, 1 );
8181
}
8282
}

lapack-netlib/LAPACKE/utils/lapacke_ctr_nancheck.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,14 @@ lapack_logical LAPACKE_ctr_nancheck( int matrix_layout, char uplo, char diag,
6868
if( ( colmaj || lower ) && !( colmaj && lower ) ) {
6969
for( j = st; j < n; j++ ) {
7070
for( i = 0; i < MIN( j+1-st, lda ); i++ ) {
71-
if( LAPACK_CISNAN( a[i+j*lda] ) )
71+
if( LAPACK_CISNAN( a[i+(size_t)j*lda] ) )
7272
return (lapack_logical) 1;
7373
}
7474
}
7575
} else {
7676
for( j = 0; j < n-st; j++ ) {
7777
for( i = j+st; i < MIN( n, lda ); i++ ) {
78-
if( LAPACK_CISNAN( a[i+j*lda] ) )
78+
if( LAPACK_CISNAN( a[i+(size_t)j*lda] ) )
7979
return (lapack_logical) 1;
8080
}
8181
}

lapack-netlib/LAPACKE/utils/lapacke_ctz_nancheck.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,35 +103,40 @@ lapack_logical LAPACKE_ctz_nancheck( int matrix_layout, char direct, char uplo,
103103
}
104104

105105
/* Initial offsets and sizes of triangular and rectangular parts */
106-
lapack_int tri_offset = 0;
106+
size_t tri_offset = 0;
107107
lapack_int tri_n = MIN(m,n);
108-
lapack_int rect_offset = -1;
108+
size_t rect_offset = 0;
109+
lapack_logical check_rect = 0;
109110
lapack_int rect_m = ( m > n ) ? m - n : m;
110111
lapack_int rect_n = ( n > m ) ? n - m : n;
111112

112113
/* Fix offsets depending on the shape of the matrix */
113114
if( front ) {
114115
if( lower && m > n ) {
115-
rect_offset = tri_n * ( !colmaj ? lda : 1 );
116+
rect_offset = (size_t)tri_n * ( !colmaj ? lda : 1 );
117+
check_rect = 1;
116118
} else if( !lower && n > m ) {
117-
rect_offset = tri_n * ( colmaj ? lda : 1 );
119+
rect_offset = (size_t)tri_n * ( colmaj ? lda : 1 );
120+
check_rect = 1;
118121
}
119122
} else {
120123
if( m > n ) {
121-
tri_offset = rect_m * ( !colmaj ? lda : 1 );
124+
tri_offset = (size_t)rect_m * ( !colmaj ? lda : 1 );
122125
if( !lower ) {
123126
rect_offset = 0;
127+
check_rect = 1;
124128
}
125129
} else if( n > m ) {
126-
tri_offset = rect_n * ( colmaj ? lda : 1 );
130+
tri_offset = (size_t)rect_n * ( colmaj ? lda : 1 );
127131
if( lower ) {
128132
rect_offset = 0;
133+
check_rect = 1;
129134
}
130135
}
131136
}
132137

133138
/* Check rectangular part */
134-
if( rect_offset >= 0 ) {
139+
if( check_rect ) {
135140
if( LAPACKE_cge_nancheck( matrix_layout, rect_m, rect_n,
136141
&a[rect_offset], lda) ) {
137142
return (lapack_logical) 1;

lapack-netlib/LAPACKE/utils/lapacke_d_nancheck.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ lapack_logical LAPACKE_d_nancheck( lapack_int n,
4242
if( incx == 0 ) return (lapack_logical) LAPACK_DISNAN( x[0] );
4343
inc = ( incx > 0 ) ? incx : -incx ;
4444

45-
for( i = 0; i < n*inc; i+=inc ) {
46-
if( LAPACK_DISNAN( x[i] ) )
45+
for( i = 0; i < n; i++ ) {
46+
if( LAPACK_DISNAN( x[(size_t)i*inc] ) )
4747
return (lapack_logical) 1;
4848
}
4949
return (lapack_logical) 0;

0 commit comments

Comments
 (0)