diff options
author | lulf <lulf@FreeBSD.org> | 2008-07-08 17:34:50 +0000 |
---|---|---|
committer | lulf <lulf@FreeBSD.org> | 2008-07-08 17:34:50 +0000 |
commit | 1547b99716941b9b7d256bef62d3fa4955880949 (patch) | |
tree | 5b3be73bdbe84255bd046a32bc817c208bfefb52 /lib/libgeom | |
parent | e31c8aa8e526df26ff15a5aab776940a6ebaf2aa (diff) | |
download | FreeBSD-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.c | 22 | ||||
-rw-r--r-- | lib/libgeom/geom_getxml.c | 32 | ||||
-rw-r--r-- | lib/libgeom/geom_xml2tree.c | 37 |
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; |