Skip to content

Commit c81f5f3

Browse files
committed
eigs: Avoid some potential integer wrap-around issues with Fortran integers.
* liboctave/numeric/eigs-base.cc (EigsRealSymmetricMatrix, EigsRealSymmetricMatrixShift, EigsRealSymmetricFunc, EigsRealNonSymmetricMatrix, EigsRealNonSymmetricMatrixShift, EigsRealNonSymmetricFunc, EigsComplexNonSymmetricMatrix, EigsComplexNonSymmetricMatrixShift, EigsComplexNonSymmetricFunc): Check for integer wrap-around when calculating the size of some buffers for Fortran functions. This slightly improves potential issues flagged by the "cpp/integer-multiplication-cast-to-long" rule of CodeQL.
1 parent b8ac5bf commit c81f5f3

File tree

1 file changed

+92
-18
lines changed

1 file changed

+92
-18
lines changed

liboctave/numeric/eigs-base.cc

Lines changed: 92 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "dSparse.h"
4242
#include "eigs-base.h"
4343
#include "lo-ieee.h"
44+
#include "lo-utils.h"
4445
#include "lu.h"
4546
#include "mx-ops.h"
4647
#include "oct-error.h"
@@ -915,9 +916,17 @@ EigsRealSymmetricMatrix (const M& m, const std::string typ,
915916

916917
F77_INT ido = 0;
917918
int iter = 0;
918-
F77_INT lwork = p * (p + 8);
919+
F77_INT elems;
920+
F77_INT lwork;
919921

920-
OCTAVE_LOCAL_BUFFER (double, v, n * p);
922+
if (octave::math::int_multiply_overflow (n, p, &elems))
923+
(*current_liboctave_error_handler)
924+
("eigs: array too large for Fortran integers");
925+
if (octave::math::int_multiply_overflow (p, p + 8, &lwork))
926+
(*current_liboctave_error_handler)
927+
("eigs: array too large for Fortran integers");
928+
929+
OCTAVE_LOCAL_BUFFER (double, v, elems);
921930
OCTAVE_LOCAL_BUFFER (double, workl, lwork);
922931
OCTAVE_LOCAL_BUFFER (double, workd, 3 * n);
923932
double *presid = resid.rwdata ();
@@ -1190,9 +1199,17 @@ EigsRealSymmetricMatrixShift (const M& m, double sigma,
11901199
if (! LuAminusSigmaB (m, b, cholB, permB, sigma, L, U, P, Q, r))
11911200
return -1;
11921201

1193-
F77_INT lwork = p * (p + 8);
1202+
F77_INT elems;
1203+
F77_INT lwork;
11941204

1195-
OCTAVE_LOCAL_BUFFER (double, v, n * p);
1205+
if (octave::math::int_multiply_overflow (n, p, &elems))
1206+
(*current_liboctave_error_handler)
1207+
("eigs: array too large for Fortran integers");
1208+
if (octave::math::int_multiply_overflow (p, p + 8, &lwork))
1209+
(*current_liboctave_error_handler)
1210+
("eigs: array too large for Fortran integers");
1211+
1212+
OCTAVE_LOCAL_BUFFER (double, v, elems);
11961213
OCTAVE_LOCAL_BUFFER (double, workl, lwork);
11971214
OCTAVE_LOCAL_BUFFER (double, workd, 3 * n);
11981215
double *presid = resid.rwdata ();
@@ -1533,9 +1550,17 @@ EigsRealSymmetricFunc (EigsFunc fcn, octave_idx_type n_arg,
15331550

15341551
F77_INT ido = 0;
15351552
int iter = 0;
1536-
F77_INT lwork = p * (p + 8);
1553+
F77_INT elems;
1554+
F77_INT lwork;
1555+
1556+
if (octave::math::int_multiply_overflow (n, p, &elems))
1557+
(*current_liboctave_error_handler)
1558+
("eigs: array too large for Fortran integers");
1559+
if (octave::math::int_multiply_overflow (p, p + 8, &lwork))
1560+
(*current_liboctave_error_handler)
1561+
("eigs: array too large for Fortran integers");
15371562

1538-
OCTAVE_LOCAL_BUFFER (double, v, n * p);
1563+
OCTAVE_LOCAL_BUFFER (double, v, elems);
15391564
OCTAVE_LOCAL_BUFFER (double, workl, lwork);
15401565
OCTAVE_LOCAL_BUFFER (double, workd, 3 * n);
15411566
double *presid = resid.rwdata ();
@@ -1889,9 +1914,17 @@ EigsRealNonSymmetricMatrix (const M& m, const std::string typ,
18891914

18901915
F77_INT ido = 0;
18911916
int iter = 0;
1892-
F77_INT lwork = 3 * p * (p + 2);
1917+
F77_INT elems;
1918+
F77_INT lwork;
18931919

1894-
OCTAVE_LOCAL_BUFFER (double, v, n * (p + 1));
1920+
if (octave::math::int_multiply_overflow (n, p + 1, &elems))
1921+
(*current_liboctave_error_handler)
1922+
("eigs: array too large for Fortran integers");
1923+
if (octave::math::int_multiply_overflow (3 * p, p + 2, &lwork))
1924+
(*current_liboctave_error_handler)
1925+
("eigs: array too large for Fortran integers");
1926+
1927+
OCTAVE_LOCAL_BUFFER (double, v, elems);
18951928
OCTAVE_LOCAL_BUFFER (double, workl, lwork + 1);
18961929
OCTAVE_LOCAL_BUFFER (double, workd, 3 * n + 1);
18971930
double *presid = resid.rwdata ();
@@ -2224,9 +2257,17 @@ EigsRealNonSymmetricMatrixShift (const M& m, double sigmar,
22242257
if (! LuAminusSigmaB (m, b, cholB, permB, sigmar, L, U, P, Q, r))
22252258
return -1;
22262259

2227-
F77_INT lwork = 3 * p * (p + 2);
2260+
F77_INT elems;
2261+
F77_INT lwork;
2262+
2263+
if (octave::math::int_multiply_overflow (n, p + 1, &elems))
2264+
(*current_liboctave_error_handler)
2265+
("eigs: array too large for Fortran integers");
2266+
if (octave::math::int_multiply_overflow (3 * p, p + 2, &lwork))
2267+
(*current_liboctave_error_handler)
2268+
("eigs: array too large for Fortran integers");
22282269

2229-
OCTAVE_LOCAL_BUFFER (double, v, n * (p + 1));
2270+
OCTAVE_LOCAL_BUFFER (double, v, elems);
22302271
OCTAVE_LOCAL_BUFFER (double, workl, lwork + 1);
22312272
OCTAVE_LOCAL_BUFFER (double, workd, 3 * n + 1);
22322273
double *presid = resid.rwdata ();
@@ -2635,11 +2676,20 @@ EigsRealNonSymmetricFunc (EigsFunc fcn, octave_idx_type n_arg,
26352676

26362677
F77_INT ido = 0;
26372678
int iter = 0;
2638-
F77_INT lwork = 3 * p * (p + 2);
2679+
F77_INT elems;
2680+
F77_INT lwork;
2681+
2682+
if (octave::math::int_multiply_overflow (n, p + 1, &elems))
2683+
(*current_liboctave_error_handler)
2684+
("eigs: array too large for Fortran integers");
2685+
if (octave::math::int_multiply_overflow (3 * p, p + 2, &lwork))
2686+
(*current_liboctave_error_handler)
2687+
("eigs: array too large for Fortran integers");
26392688

2640-
OCTAVE_LOCAL_BUFFER (double, v, n * (p + 1));
2689+
OCTAVE_LOCAL_BUFFER (double, v, elems);
26412690
OCTAVE_LOCAL_BUFFER (double, workl, lwork + 1);
26422691
OCTAVE_LOCAL_BUFFER (double, workd, 3 * n + 1);
2692+
26432693
double *presid = resid.rwdata ();
26442694

26452695
do
@@ -3055,9 +3105,17 @@ EigsComplexNonSymmetricMatrix (const M& m, const std::string typ,
30553105

30563106
F77_INT ido = 0;
30573107
int iter = 0;
3058-
F77_INT lwork = p * (3 * p + 5);
3108+
F77_INT elems;
3109+
F77_INT lwork;
3110+
3111+
if (octave::math::int_multiply_overflow (n, p, &elems))
3112+
(*current_liboctave_error_handler)
3113+
("eigs: array too large for Fortran integers");
3114+
if (octave::math::int_multiply_overflow (p, 3 * p + 5, &lwork))
3115+
(*current_liboctave_error_handler)
3116+
("eigs: array too large for Fortran integers");
30593117

3060-
OCTAVE_LOCAL_BUFFER (Complex, v, n * p);
3118+
OCTAVE_LOCAL_BUFFER (Complex, v, elems);
30613119
OCTAVE_LOCAL_BUFFER (Complex, workl, lwork);
30623120
OCTAVE_LOCAL_BUFFER (Complex, workd, 3 * n);
30633121
OCTAVE_LOCAL_BUFFER (double, rwork, p);
@@ -3342,9 +3400,17 @@ EigsComplexNonSymmetricMatrixShift (const M& m, Complex sigma,
33423400
if (! LuAminusSigmaB (m, b, cholB, permB, sigma, L, U, P, Q, r))
33433401
return -1;
33443402

3345-
F77_INT lwork = p * (3 * p + 5);
3403+
F77_INT elems;
3404+
F77_INT lwork;
3405+
3406+
if (octave::math::int_multiply_overflow (n, p, &elems))
3407+
(*current_liboctave_error_handler)
3408+
("eigs: array too large for Fortran integers");
3409+
if (octave::math::int_multiply_overflow (p, 3 * p + 5, &lwork))
3410+
(*current_liboctave_error_handler)
3411+
("eigs: array too large for Fortran integers");
33463412

3347-
OCTAVE_LOCAL_BUFFER (Complex, v, n * p);
3413+
OCTAVE_LOCAL_BUFFER (Complex, v, elems);
33483414
OCTAVE_LOCAL_BUFFER (Complex, workl, lwork);
33493415
OCTAVE_LOCAL_BUFFER (Complex, workd, 3 * n);
33503416
OCTAVE_LOCAL_BUFFER (double, rwork, p);
@@ -3703,9 +3769,17 @@ EigsComplexNonSymmetricFunc (EigsComplexFunc fcn, octave_idx_type n_arg,
37033769

37043770
F77_INT ido = 0;
37053771
int iter = 0;
3706-
F77_INT lwork = p * (3 * p + 5);
3772+
F77_INT elems;
3773+
F77_INT lwork;
3774+
3775+
if (octave::math::int_multiply_overflow (n, p, &elems))
3776+
(*current_liboctave_error_handler)
3777+
("eigs: array too large for Fortran integers");
3778+
if (octave::math::int_multiply_overflow (p, 3 * p + 5, &lwork))
3779+
(*current_liboctave_error_handler)
3780+
("eigs: array too large for Fortran integers");
37073781

3708-
OCTAVE_LOCAL_BUFFER (Complex, v, n * p);
3782+
OCTAVE_LOCAL_BUFFER (Complex, v, elems);
37093783
OCTAVE_LOCAL_BUFFER (Complex, workl, lwork);
37103784
OCTAVE_LOCAL_BUFFER (Complex, workd, 3 * n);
37113785
OCTAVE_LOCAL_BUFFER (double, rwork, p);

0 commit comments

Comments
 (0)