Commit d65a679a authored by Pino Toscano's avatar Pino Toscano Committed by Richard W.M. Jones

Avoid VLAs with size depending on user input

Do not use var-length arrays with sizes from user input (like
parameters), since they may grow the stack too much.

Instead, allocate the memory on the heap.
parent ff8adda9
......@@ -481,7 +481,7 @@ sub gen_c_code
CAMLlocal1 (rv);
virConnectPtr conn = Connect_val (connv);
int i = Int_val (iv);
int ids[i], r;
int *ids, r;
/* Some libvirt List* functions still throw exceptions if i == 0,
* so catch that and return an empty array directly. This changes
......@@ -493,12 +493,17 @@ sub gen_c_code
CAMLreturn (rv);
}
ids = malloc (sizeof (*ids) * i);
if (ids == NULL)
caml_raise_out_of_memory ();
NONBLOCKING (r = $c_name (conn, ids, i));
CHECK_ERROR (r == -1, \"$c_name\");
CHECK_ERROR_CLEANUP (r == -1, free (ids), \"$c_name\");
rv = caml_alloc (r, 0);
for (i = 0; i < r; ++i)
Store_field (rv, i, Val_int (ids[i]));
free (ids);
CAMLreturn (rv);
"
......@@ -507,7 +512,7 @@ sub gen_c_code
CAMLlocal2 (rv, strv);
" . gen_unpack_args ($1) . "
int i = Int_val (iv);
char *names[i];
char **names;
int r;
/* Some libvirt List* functions still throw exceptions if i == 0,
......@@ -520,8 +525,12 @@ sub gen_c_code
CAMLreturn (rv);
}
names = malloc (sizeof (*names) * i);
if (names == NULL)
caml_raise_out_of_memory ();
NONBLOCKING (r = $c_name ($1, names, i));
CHECK_ERROR (r == -1, \"$c_name\");
CHECK_ERROR_CLEANUP (r == -1, free (names), \"$c_name\");
rv = caml_alloc (r, 0);
for (i = 0; i < r; ++i) {
......@@ -529,6 +538,7 @@ sub gen_c_code
Store_field (rv, i, strv);
free (names[i]);
}
free (names);
CAMLreturn (rv);
"
......
......@@ -161,7 +161,7 @@ ocaml_libvirt_connect_list_domains (value connv, value iv)
CAMLlocal1 (rv);
virConnectPtr conn = Connect_val (connv);
int i = Int_val (iv);
int ids[i], r;
int *ids, r;
/* Some libvirt List* functions still throw exceptions if i == 0,
* so catch that and return an empty array directly. This changes
......@@ -173,12 +173,17 @@ ocaml_libvirt_connect_list_domains (value connv, value iv)
CAMLreturn (rv);
}
ids = malloc (sizeof (*ids) * i);
if (ids == NULL)
caml_raise_out_of_memory ();
NONBLOCKING (r = virConnectListDomains (conn, ids, i));
CHECK_ERROR (r == -1, "virConnectListDomains");
CHECK_ERROR_CLEANUP (r == -1, free (ids), "virConnectListDomains");
rv = caml_alloc (r, 0);
for (i = 0; i < r; ++i)
Store_field (rv, i, Val_int (ids[i]));
free (ids);
CAMLreturn (rv);
}
......@@ -213,7 +218,7 @@ ocaml_libvirt_connect_list_defined_domains (value connv, value iv)
CAMLlocal2 (rv, strv);
virConnectPtr conn = Connect_val (connv);
int i = Int_val (iv);
char *names[i];
char **names;
int r;
/* Some libvirt List* functions still throw exceptions if i == 0,
......@@ -226,8 +231,12 @@ ocaml_libvirt_connect_list_defined_domains (value connv, value iv)
CAMLreturn (rv);
}
names = malloc (sizeof (*names) * i);
if (names == NULL)
caml_raise_out_of_memory ();
NONBLOCKING (r = virConnectListDefinedDomains (conn, names, i));
CHECK_ERROR (r == -1, "virConnectListDefinedDomains");
CHECK_ERROR_CLEANUP (r == -1, free (names), "virConnectListDefinedDomains");
rv = caml_alloc (r, 0);
for (i = 0; i < r; ++i) {
......@@ -235,6 +244,7 @@ ocaml_libvirt_connect_list_defined_domains (value connv, value iv)
Store_field (rv, i, strv);
free (names[i]);
}
free (names);
CAMLreturn (rv);
}
......@@ -269,7 +279,7 @@ ocaml_libvirt_connect_list_networks (value connv, value iv)
CAMLlocal2 (rv, strv);
virConnectPtr conn = Connect_val (connv);
int i = Int_val (iv);
char *names[i];
char **names;
int r;
/* Some libvirt List* functions still throw exceptions if i == 0,
......@@ -282,8 +292,12 @@ ocaml_libvirt_connect_list_networks (value connv, value iv)
CAMLreturn (rv);
}
names = malloc (sizeof (*names) * i);
if (names == NULL)
caml_raise_out_of_memory ();
NONBLOCKING (r = virConnectListNetworks (conn, names, i));
CHECK_ERROR (r == -1, "virConnectListNetworks");
CHECK_ERROR_CLEANUP (r == -1, free (names), "virConnectListNetworks");
rv = caml_alloc (r, 0);
for (i = 0; i < r; ++i) {
......@@ -291,6 +305,7 @@ ocaml_libvirt_connect_list_networks (value connv, value iv)
Store_field (rv, i, strv);
free (names[i]);
}
free (names);
CAMLreturn (rv);
}
......@@ -325,7 +340,7 @@ ocaml_libvirt_connect_list_defined_networks (value connv, value iv)
CAMLlocal2 (rv, strv);
virConnectPtr conn = Connect_val (connv);
int i = Int_val (iv);
char *names[i];
char **names;
int r;
/* Some libvirt List* functions still throw exceptions if i == 0,
......@@ -338,8 +353,12 @@ ocaml_libvirt_connect_list_defined_networks (value connv, value iv)
CAMLreturn (rv);
}
names = malloc (sizeof (*names) * i);
if (names == NULL)
caml_raise_out_of_memory ();
NONBLOCKING (r = virConnectListDefinedNetworks (conn, names, i));
CHECK_ERROR (r == -1, "virConnectListDefinedNetworks");
CHECK_ERROR_CLEANUP (r == -1, free (names), "virConnectListDefinedNetworks");
rv = caml_alloc (r, 0);
for (i = 0; i < r; ++i) {
......@@ -347,6 +366,7 @@ ocaml_libvirt_connect_list_defined_networks (value connv, value iv)
Store_field (rv, i, strv);
free (names[i]);
}
free (names);
CAMLreturn (rv);
}
......@@ -381,7 +401,7 @@ ocaml_libvirt_connect_list_storage_pools (value connv, value iv)
CAMLlocal2 (rv, strv);
virConnectPtr conn = Connect_val (connv);
int i = Int_val (iv);
char *names[i];
char **names;
int r;
/* Some libvirt List* functions still throw exceptions if i == 0,
......@@ -394,8 +414,12 @@ ocaml_libvirt_connect_list_storage_pools (value connv, value iv)
CAMLreturn (rv);
}
names = malloc (sizeof (*names) * i);
if (names == NULL)
caml_raise_out_of_memory ();
NONBLOCKING (r = virConnectListStoragePools (conn, names, i));
CHECK_ERROR (r == -1, "virConnectListStoragePools");
CHECK_ERROR_CLEANUP (r == -1, free (names), "virConnectListStoragePools");
rv = caml_alloc (r, 0);
for (i = 0; i < r; ++i) {
......@@ -403,6 +427,7 @@ ocaml_libvirt_connect_list_storage_pools (value connv, value iv)
Store_field (rv, i, strv);
free (names[i]);
}
free (names);
CAMLreturn (rv);
}
......@@ -437,7 +462,7 @@ ocaml_libvirt_connect_list_defined_storage_pools (value connv, value iv)
CAMLlocal2 (rv, strv);
virConnectPtr conn = Connect_val (connv);
int i = Int_val (iv);
char *names[i];
char **names;
int r;
/* Some libvirt List* functions still throw exceptions if i == 0,
......@@ -450,8 +475,12 @@ ocaml_libvirt_connect_list_defined_storage_pools (value connv, value iv)
CAMLreturn (rv);
}
names = malloc (sizeof (*names) * i);
if (names == NULL)
caml_raise_out_of_memory ();
NONBLOCKING (r = virConnectListDefinedStoragePools (conn, names, i));
CHECK_ERROR (r == -1, "virConnectListDefinedStoragePools");
CHECK_ERROR_CLEANUP (r == -1, free (names), "virConnectListDefinedStoragePools");
rv = caml_alloc (r, 0);
for (i = 0; i < r; ++i) {
......@@ -459,6 +488,7 @@ ocaml_libvirt_connect_list_defined_storage_pools (value connv, value iv)
Store_field (rv, i, strv);
free (names[i]);
}
free (names);
CAMLreturn (rv);
}
......@@ -1795,7 +1825,7 @@ ocaml_libvirt_storage_pool_list_volumes (value poolv, value iv)
CAMLlocal2 (rv, strv);
virStoragePoolPtr pool = Pool_val (poolv);
int i = Int_val (iv);
char *names[i];
char **names;
int r;
/* Some libvirt List* functions still throw exceptions if i == 0,
......@@ -1808,8 +1838,12 @@ ocaml_libvirt_storage_pool_list_volumes (value poolv, value iv)
CAMLreturn (rv);
}
names = malloc (sizeof (*names) * i);
if (names == NULL)
caml_raise_out_of_memory ();
NONBLOCKING (r = virStoragePoolListVolumes (pool, names, i));
CHECK_ERROR (r == -1, "virStoragePoolListVolumes");
CHECK_ERROR_CLEANUP (r == -1, free (names), "virStoragePoolListVolumes");
rv = caml_alloc (r, 0);
for (i = 0; i < r; ++i) {
......@@ -1817,6 +1851,7 @@ ocaml_libvirt_storage_pool_list_volumes (value poolv, value iv)
Store_field (rv, i, strv);
free (names[i]);
}
free (names);
CAMLreturn (rv);
}
......
......@@ -284,16 +284,21 @@ ocaml_libvirt_connect_node_get_cells_free_memory (value connv,
int start = Int_val (startv);
int max = Int_val (maxv);
int r, i;
unsigned long long freemems[max];
unsigned long long *freemems;
freemems = malloc(sizeof (*freemems) * max);
if (freemems == NULL)
caml_raise_out_of_memory ();
NONBLOCKING (r = virNodeGetCellsFreeMemory (conn, freemems, start, max));
CHECK_ERROR (r == -1, "virNodeGetCellsFreeMemory");
CHECK_ERROR_CLEANUP (r == -1, free (freemems), "virNodeGetCellsFreeMemory");
rv = caml_alloc (r, 0);
for (i = 0; i < r; ++i) {
iv = caml_copy_int64 ((int64_t) freemems[i]);
Store_field (rv, i, iv);
}
free (freemems);
CAMLreturn (rv);
}
......@@ -421,11 +426,15 @@ ocaml_libvirt_domain_get_scheduler_parameters (value domv, value nparamsv)
CAMLlocal4 (rv, v, v2, v3);
virDomainPtr dom = Domain_val (domv);
int nparams = Int_val (nparamsv);
virSchedParameter params[nparams];
virSchedParameterPtr params;
int r, i;
params = malloc (sizeof (*params) * nparams);
if (params == NULL)
caml_raise_out_of_memory ();
NONBLOCKING (r = virDomainGetSchedulerParameters (dom, params, &nparams));
CHECK_ERROR (r == -1, "virDomainGetSchedulerParameters");
CHECK_ERROR_CLEANUP (r == -1, free (params), "virDomainGetSchedulerParameters");
rv = caml_alloc (nparams, 0);
for (i = 0; i < nparams; ++i) {
......@@ -461,6 +470,7 @@ ocaml_libvirt_domain_get_scheduler_parameters (value domv, value nparamsv)
}
Store_field (v, 1, v2);
}
free (params);
CAMLreturn (rv);
}
......@@ -471,10 +481,14 @@ ocaml_libvirt_domain_set_scheduler_parameters (value domv, value paramsv)
CAMLlocal1 (v);
virDomainPtr dom = Domain_val (domv);
int nparams = Wosize_val (paramsv);
virSchedParameter params[nparams];
virSchedParameterPtr params;
int r, i;
char *name;
params = malloc (sizeof (*params) * nparams);
if (params == NULL)
caml_raise_out_of_memory ();
for (i = 0; i < nparams; ++i) {
v = Field (paramsv, i); /* Points to the two-element tuple. */
name = String_val (Field (v, 0));
......@@ -512,6 +526,7 @@ ocaml_libvirt_domain_set_scheduler_parameters (value domv, value paramsv)
}
NONBLOCKING (r = virDomainSetSchedulerParameters (dom, params, nparams));
free (params);
CHECK_ERROR (r == -1, "virDomainSetSchedulerParameters");
CAMLreturn (Val_unit);
......@@ -554,15 +569,21 @@ ocaml_libvirt_domain_get_vcpus (value domv, value maxinfov, value maplenv)
virDomainPtr dom = Domain_val (domv);
int maxinfo = Int_val (maxinfov);
int maplen = Int_val (maplenv);
virVcpuInfo info[maxinfo];
unsigned char cpumaps[maxinfo * maplen];
virVcpuInfoPtr info;
unsigned char *cpumaps;
int r, i;
memset (info, 0, sizeof (virVcpuInfo) * maxinfo);
memset (cpumaps, 0, maxinfo * maplen);
info = calloc (maxinfo, sizeof (*info));
if (info == NULL)
caml_raise_out_of_memory ();
cpumaps = calloc (maxinfo * maplen, sizeof (*cpumaps));
if (cpumaps == NULL) {
free (info);
caml_raise_out_of_memory ();
}
NONBLOCKING (r = virDomainGetVcpus (dom, info, maxinfo, cpumaps, maplen));
CHECK_ERROR (r == -1, "virDomainPinVcpu");
CHECK_ERROR_CLEANUP (r == -1, free (info); free (cpumaps), "virDomainPinVcpu");
/* Copy the virVcpuInfo structures. */
infov = caml_alloc (maxinfo, 0);
......@@ -584,6 +605,9 @@ ocaml_libvirt_domain_get_vcpus (value domv, value maxinfov, value maplenv)
Store_field (rv, 1, infov);
Store_field (rv, 2, strv);
free (info);
free (cpumaps);
CAMLreturn (rv);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment