From ab64aee002958c27fcc82b54d3e3e0a6f0ed41fe Mon Sep 17 00:00:00 2001 From: kabeleh <43334074+kabeleh@users.noreply.github.com> Date: Mon, 9 Feb 2026 21:25:10 +0200 Subject: [PATCH 1/3] Fix buffer size calculation and memory alignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix misaligned memory access in evolver_ndf15 buffer layout: The ndf15 evolver allocates a single contiguous buffer and carves it into sub-arrays for doubles, an int array (interpidx), a double-pointer array (dif), and a second double region for backward differences. The original layout placed the int array (neqp × sizeof(int)) between the double arrays and the double-pointer array: [15×neqp doubles] [neqp ints] [neqp double*] [(7×neq+1) doubles] When neqp is odd, neqp × 4 bytes leaves the subsequent double* and double regions at a 4-byte boundary, rather than the 8-byte alignment required for these types. This constitutes undefined behaviour in C11 and is flagged at runtime by the -fsanitize=undefined CCFLAG / LDFLAG as misaligned load/store errors during thermodynamics integration. The solution is to move the int array to the end of the buffer, after all double and double* regions: [15×neqp doubles] [neqp double*] [(7×neq+1) doubles] [neqp ints] Since malloc returns memory aligned to at least 8 bytes, and all regions before the int array are multiples of 8 bytes in size, every double and double* access is now aligned. The int array at the tail has no alignment requirement beyond 4 bytes, so placing it last is safe. The total buffer size is unchanged. Verified clean under -fsanitize=undefined, -fsanitize=address, and -fsanitize=thread. --- tools/evolver_ndf15.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/evolver_ndf15.c b/tools/evolver_ndf15.c index 0d2937235..f379fe361 100644 --- a/tools/evolver_ndf15.c +++ b/tools/evolver_ndf15.c @@ -119,9 +119,9 @@ int evolver_ndf15( buffer_size= 15*neqp*sizeof(double) - +neqp*sizeof(int) +neqp*sizeof(double*) - +(7*neq+1)*sizeof(double); + +(7*neq+1)*sizeof(double) + +neqp*sizeof(int); /* the double and double* (pointer) are 8-bit. For odd neqp, it happens that the int (4-bit) misaligns the memory */ class_alloc(buffer, buffer_size, @@ -143,10 +143,12 @@ int evolver_ndf15( tempvec1 =yppinterp+neqp; tempvec2 =tempvec1+neqp; - interpidx=(int*)(tempvec2+neqp); + /*interpidx=(int*)(tempvec2+neqp); - dif =(double**)(interpidx+neqp); + dif =(double**)(interpidx+neqp);*/ + dif = (double **)(tempvec2 + neqp); dif[1] =(double*)(dif+neqp); + interpidx=(int *)(dif[1] + 7 * neq + 1); /* put int array last for memory alignment */ for(j=2;j<=neq;j++) dif[j] = dif[j-1]+7; /* Set row pointers... */ dif[0] = NULL; /* for (ii=0;ii<(7*neq+1);ii++) dif[1][ii]=0.; */ From 1e7c3b6099a6f7b2d02fa4872db1f0ad041744fc Mon Sep 17 00:00:00 2001 From: Kay Lehnert <43334074+kabeleh@users.noreply.github.com> Date: Wed, 18 Feb 2026 16:57:50 +0200 Subject: [PATCH 2/3] Increase base path size from 1000 to 1024 There was a tiny chance that line 50 in input.h if (flag_temp == _TRUE_) \ 49 { \ 50 strcpy(destination, string_temp); \ 51 } might cause a bufferoverflow. It's very unlikely to encounter this, but no downside in preventing it. --- include/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/common.h b/include/common.h index b76b0068e..008b79843 100644 --- a/include/common.h +++ b/include/common.h @@ -29,7 +29,7 @@ typedef char ErrorMsg[_ERRORMSGSIZE_]; /**< Generic error messages (there is such a field in each structure) */ #define _FILENAMESIZE_ 256 /**< size of the string read in each line of the file (extra characters not taken into account) */ -#define _BASEPATHSIZE_ 1000 /**< allowed size of the base path */ +#define _BASEPATHSIZE_ 1024 /**< allowed size of the base path */ typedef char FileName[_FILENAMESIZE_+_BASEPATHSIZE_]; #define _SUFFIXNAMESIZE_ 4 /**< maximum size of the short string appended to file names to account for initial conditions, etc. */ From c634d1638f8c3af5e0115e134eb3bc9acf7e209e Mon Sep 17 00:00:00 2001 From: Kay Lehnert <43334074+kabeleh@users.noreply.github.com> Date: Wed, 18 Feb 2026 21:56:54 +0200 Subject: [PATCH 3/3] Change REFINE to a constant in hyperspherical.c Variable length arrays are actually not supported. It's not an issue, just a compiler warning. Though, the fix is simply to define REFINE as a const int instead of just an int. Compiler is happy. --- tools/hyperspherical.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hyperspherical.c b/tools/hyperspherical.c index 937d83645..9489fb7e9 100644 --- a/tools/hyperspherical.c +++ b/tools/hyperspherical.c @@ -1029,7 +1029,7 @@ int hyperspherical_get_xmin(HyperInterpStruct *pHIS, int left_index, right_index, index_l, j; int nl = pHIS->l_size; int nx = pHIS->x_size; - int REFINE=10; + const int REFINE=10; double x[REFINE]; double Phi[REFINE]; double *phivec = pHIS->phi;