summaryrefslogtreecommitdiffstats
path: root/lib/libgeom
diff options
context:
space:
mode:
authorlulf <lulf@FreeBSD.org>2008-07-08 17:34:50 +0000
committerlulf <lulf@FreeBSD.org>2008-07-08 17:34:50 +0000
commit1547b99716941b9b7d256bef62d3fa4955880949 (patch)
tree5b3be73bdbe84255bd046a32bc817c208bfefb52 /lib/libgeom
parente31c8aa8e526df26ff15a5aab776940a6ebaf2aa (diff)
downloadFreeBSD-src-1547b99716941b9b7d256bef62d3fa4955880949.zip
FreeBSD-src-1547b99716941b9b7d256bef62d3fa4955880949.tar.gz
- 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)
Diffstat (limited to 'lib/libgeom')
-rw-r--r--lib/libgeom/geom_ctl.c22
-rw-r--r--lib/libgeom/geom_getxml.c32
-rw-r--r--lib/libgeom/geom_xml2tree.c37
3 files changed, 65 insertions, 26 deletions
diff --git a/lib/libgeom/geom_ctl.c b/lib/libgeom/geom_ctl.c
index d308849..59691cc 100644
--- a/lib/libgeom/geom_ctl.c
+++ b/lib/libgeom/geom_ctl.c
@@ -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);
}
diff --git a/lib/libgeom/geom_getxml.c b/lib/libgeom/geom_getxml.c
index 68ff91b..b27696d 100644
--- a/lib/libgeom/geom_getxml.c
+++ b/lib/libgeom/geom_getxml.c
@@ -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 */
+ 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) {
- i = sysctlbyname("kern.geom.confxml", p, &l, NULL, 0);
- if (i == 0) {
- p = realloc(p, strlen(p) + 1);
- return (p);
- }
+ if (p == NULL)
+ return (NULL);
+ if (sysctl(mib, sizep, p, &l, NULL, 0) != 0) {
free(p);
- }
- l = 0;
- i = sysctlbyname("kern.geom.confxml", NULL, &l, NULL, 0);
- if (i != 0)
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));
}
diff --git a/lib/libgeom/geom_xml2tree.c b/lib/libgeom/geom_xml2tree.c
index 7798f44..08fb394 100644
--- a/lib/libgeom/geom_xml2tree.c
+++ b/lib/libgeom/geom_xml2tree.c
@@ -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;
OpenPOWER on IntegriCloud