- Simplify the procedure of retrieving XML-data from the kernel.
- Fix a number of potential memory leaks in libgeom related to doing realloc without freeing old pointer if things go wrong. - Fix a number of places in libgeom where malloc and calloc return values were not checked. - Check malloc return value and provide sufficient warning messages when XML parsing fails. PR: kern/83464 Submitted by: Dan Lukes <dan - at - obluda.cz> Approved by: kib (mentor)
This commit is contained in:
parent
e31c8aa8e5
commit
1547b99716
@ -45,6 +45,12 @@
|
||||
#define GCTL_TABLE 1
|
||||
#include <libgeom.h>
|
||||
|
||||
/*
|
||||
* Global pointer to a string that is used to avoid an errorneous free in
|
||||
* gctl_free.
|
||||
*/
|
||||
static char nomemmsg[] = "Could not allocate memory";
|
||||
|
||||
void
|
||||
gctl_dump(struct gctl_req *req, FILE *f)
|
||||
{
|
||||
@ -105,11 +111,12 @@ gctl_set_error(struct gctl_req *req, const char *error, ...)
|
||||
static void
|
||||
gctl_check_alloc(struct gctl_req *req, void *ptr)
|
||||
{
|
||||
|
||||
if (ptr != NULL)
|
||||
return;
|
||||
gctl_set_error(req, "Could not allocate memory");
|
||||
gctl_set_error(req, nomemmsg);
|
||||
if (req->error == NULL)
|
||||
req->error = "Could not allocate memory";
|
||||
req->error = nomemmsg;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -134,7 +141,7 @@ gctl_new_arg(struct gctl_req *req)
|
||||
struct gctl_req_arg *ap;
|
||||
|
||||
req->narg++;
|
||||
req->arg = realloc(req->arg, sizeof *ap * req->narg);
|
||||
req->arg = reallocf(req->arg, sizeof *ap * req->narg);
|
||||
gctl_check_alloc(req, req->arg);
|
||||
if (req->arg == NULL) {
|
||||
req->narg = 0;
|
||||
@ -157,6 +164,8 @@ gctl_ro_param(struct gctl_req *req, const char *name, int len, const void* value
|
||||
return;
|
||||
ap->name = strdup(name);
|
||||
gctl_check_alloc(req, ap->name);
|
||||
if (ap->name == NULL)
|
||||
return;
|
||||
ap->nlen = strlen(ap->name) + 1;
|
||||
ap->value = __DECONST(void *, value);
|
||||
ap->flag = GCTL_PARAM_RD;
|
||||
@ -180,6 +189,8 @@ gctl_rw_param(struct gctl_req *req, const char *name, int len, void* value)
|
||||
return;
|
||||
ap->name = strdup(name);
|
||||
gctl_check_alloc(req, ap->name);
|
||||
if (ap->name == NULL)
|
||||
return;
|
||||
ap->nlen = strlen(ap->name) + 1;
|
||||
ap->value = value;
|
||||
ap->flag = GCTL_PARAM_RW;
|
||||
@ -201,12 +212,11 @@ gctl_issue(struct gctl_req *req)
|
||||
|
||||
req->version = GCTL_VERSION;
|
||||
req->lerror = BUFSIZ; /* XXX: arbitrary number */
|
||||
req->error = malloc(req->lerror);
|
||||
req->error = calloc(1, req->lerror);
|
||||
if (req->error == NULL) {
|
||||
gctl_check_alloc(req, req->error);
|
||||
return (req->error);
|
||||
}
|
||||
memset(req->error, 0, req->lerror);
|
||||
req->lerror--;
|
||||
fd = open(_PATH_DEV PATH_GEOM_CTL, O_RDONLY);
|
||||
if (fd < 0)
|
||||
@ -232,7 +242,7 @@ gctl_free(struct gctl_req *req)
|
||||
free(req->arg[i].name);
|
||||
}
|
||||
free(req->arg);
|
||||
if (req->error != NULL)
|
||||
if (req->error != NULL && req->error != nomemmsg)
|
||||
free(req->error);
|
||||
free(req);
|
||||
}
|
||||
|
@ -39,28 +39,22 @@ char *
|
||||
geom_getxml()
|
||||
{
|
||||
char *p;
|
||||
size_t l;
|
||||
int i;
|
||||
size_t l = 0;
|
||||
int mib[3];
|
||||
size_t sizep;
|
||||
|
||||
l = 1024 * 1024; /* Start big, realloc back */
|
||||
p = malloc(l);
|
||||
if (p) {
|
||||
i = sysctlbyname("kern.geom.confxml", p, &l, NULL, 0);
|
||||
if (i == 0) {
|
||||
p = realloc(p, strlen(p) + 1);
|
||||
return (p);
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
l = 0;
|
||||
i = sysctlbyname("kern.geom.confxml", NULL, &l, NULL, 0);
|
||||
if (i != 0)
|
||||
sizep = sizeof(mib) / sizeof(*mib);
|
||||
if (sysctlnametomib("kern.geom.confxml", mib, &sizep) != 0)
|
||||
return (NULL);
|
||||
if (sysctl(mib, sizep, NULL, &l, NULL, 0) != 0)
|
||||
return (NULL);
|
||||
l += 4096;
|
||||
p = malloc(l);
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
if (sysctl(mib, sizep, p, &l, NULL, 0) != 0) {
|
||||
free(p);
|
||||
return (NULL);
|
||||
p = malloc(l + 4096);
|
||||
i = sysctlbyname("kern.geom.confxml", p, &l, NULL, 0);
|
||||
if (i == 0) {
|
||||
p = realloc(p, strlen(p) + 1);
|
||||
return (p);
|
||||
}
|
||||
return (NULL);
|
||||
return (reallocf(p, strlen(p) + 1));
|
||||
}
|
||||
|
@ -84,6 +84,11 @@ StartElement(void *userData, const char *name, const char **attr)
|
||||
}
|
||||
if (!strcmp(name, "class") && mt->class == NULL) {
|
||||
mt->class = calloc(1, sizeof *mt->class);
|
||||
if (mt->class == NULL) {
|
||||
warn("Cannot allocate memory during processing of '%s' "
|
||||
"element", name);
|
||||
return;
|
||||
}
|
||||
mt->class->lg_id = id;
|
||||
LIST_INSERT_HEAD(&mt->mesh->lg_class, mt->class, lg_class);
|
||||
LIST_INIT(&mt->class->lg_geom);
|
||||
@ -92,6 +97,11 @@ StartElement(void *userData, const char *name, const char **attr)
|
||||
}
|
||||
if (!strcmp(name, "geom") && mt->geom == NULL) {
|
||||
mt->geom = calloc(1, sizeof *mt->geom);
|
||||
if (mt->geom == NULL) {
|
||||
warn("Cannot allocate memory during processing of '%s' "
|
||||
"element", name);
|
||||
return;
|
||||
}
|
||||
mt->geom->lg_id = id;
|
||||
LIST_INSERT_HEAD(&mt->class->lg_geom, mt->geom, lg_geom);
|
||||
LIST_INIT(&mt->geom->lg_provider);
|
||||
@ -105,6 +115,11 @@ StartElement(void *userData, const char *name, const char **attr)
|
||||
}
|
||||
if (!strcmp(name, "consumer") && mt->consumer == NULL) {
|
||||
mt->consumer = calloc(1, sizeof *mt->consumer);
|
||||
if (mt->consumer == NULL) {
|
||||
warn("Cannot allocate memory during processing of '%s' "
|
||||
"element", name);
|
||||
return;
|
||||
}
|
||||
mt->consumer->lg_id = id;
|
||||
LIST_INSERT_HEAD(&mt->geom->lg_consumer, mt->consumer,
|
||||
lg_consumer);
|
||||
@ -121,6 +136,11 @@ StartElement(void *userData, const char *name, const char **attr)
|
||||
}
|
||||
if (!strcmp(name, "provider") && mt->provider == NULL) {
|
||||
mt->provider = calloc(1, sizeof *mt->provider);
|
||||
if (mt->provider == NULL) {
|
||||
warn("Cannot allocate memory during processing of '%s' "
|
||||
"element", name);
|
||||
return;
|
||||
}
|
||||
mt->provider->lg_id = id;
|
||||
LIST_INSERT_HEAD(&mt->geom->lg_provider, mt->provider,
|
||||
lg_provider);
|
||||
@ -162,6 +182,11 @@ EndElement(void *userData, const char *name)
|
||||
mt = userData;
|
||||
sbuf_finish(mt->sbuf[mt->level]);
|
||||
p = strdup(sbuf_data(mt->sbuf[mt->level]));
|
||||
if (p == NULL) {
|
||||
warn("Cannot allocate memory during processing of '%s' "
|
||||
"element", name);
|
||||
return;
|
||||
}
|
||||
sbuf_delete(mt->sbuf[mt->level]);
|
||||
mt->sbuf[mt->level] = NULL;
|
||||
mt->level--;
|
||||
@ -212,8 +237,18 @@ EndElement(void *userData, const char *name)
|
||||
}
|
||||
|
||||
if (mt->config != NULL) {
|
||||
gc = calloc(sizeof *gc, 1);
|
||||
gc = calloc(1, sizeof *gc);
|
||||
if (gc == NULL) {
|
||||
warn("Cannot allocate memory during processing of '%s' "
|
||||
"element", name);
|
||||
return;
|
||||
}
|
||||
gc->lg_name = strdup(name);
|
||||
if (gc->lg_name == NULL) {
|
||||
warn("Cannot allocate memory during processing of '%s' "
|
||||
"element", name);
|
||||
return;
|
||||
}
|
||||
gc->lg_val = p;
|
||||
LIST_INSERT_HEAD(mt->config, gc, lg_config);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user