aboutsummaryrefslogtreecommitdiff
path: root/lib/libdevinfo
diff options
context:
space:
mode:
authorEric van Gyzen <vangyzen@FreeBSD.org>2020-08-04 21:05:53 +0000
committerEric van Gyzen <vangyzen@FreeBSD.org>2020-08-04 21:05:53 +0000
commit32592d86dfad2781a260387082ccdf251bc45abd (patch)
treecf5749e40ea374db5696591b40e648125a61ae35 /lib/libdevinfo
parentb64dca2b6f1e2d670c6aaa4f592e6424eb80b7b4 (diff)
downloadsrc-32592d86dfad2781a260387082ccdf251bc45abd.tar.gz
src-32592d86dfad2781a260387082ccdf251bc45abd.zip
devinfo: fix memory leak on error paths
Refactor to create devinfo_free_dev(). Call it to plug a memory leak on two error paths in devinfo_init_devices(). Reported by: Coverity MFC after: 2 weeks Sponsored by: Dell EMC Isilon
Notes
Notes: svn path=/head/; revision=363866
Diffstat (limited to 'lib/libdevinfo')
-rw-r--r--lib/libdevinfo/devinfo.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/lib/libdevinfo/devinfo.c b/lib/libdevinfo/devinfo.c
index c4cd8d78ba94..581d3464cd0e 100644
--- a/lib/libdevinfo/devinfo.c
+++ b/lib/libdevinfo/devinfo.c
@@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
static int devinfo_init_devices(int generation);
static int devinfo_init_resources(int generation);
+static void devinfo_free_dev(struct devinfo_i_dev *dd);
TAILQ_HEAD(,devinfo_i_dev) devinfo_dev;
TAILQ_HEAD(,devinfo_i_rman) devinfo_rman;
@@ -225,7 +226,7 @@ devinfo_init_devices(int generation)
rlen, sizeof(udev));
return (EINVAL);
}
- if ((dd = malloc(sizeof(*dd))) == NULL)
+ if ((dd = calloc(1, sizeof(*dd))) == NULL)
return(ENOMEM);
dd->dd_dev.dd_handle = udev.dv_handle;
dd->dd_dev.dd_parent = udev.dv_parent;
@@ -242,10 +243,14 @@ devinfo_init_devices(int generation)
dd->dd_location = NULL;
#define UNPACK(x) \
dd->dd_dev.x = dd->x = strdup(walker); \
- if (dd->x == NULL) \
+ if (dd->x == NULL) { \
+ devinfo_free_dev(dd); \
return(ENOMEM); \
- if (walker + strnlen(walker, ep - walker) >= ep) \
+ } \
+ if (walker + strnlen(walker, ep - walker) >= ep) { \
+ devinfo_free_dev(dd); \
return(EINVAL); \
+ } \
walker += strlen(walker) + 1;
UNPACK(dd_name);
@@ -365,6 +370,20 @@ devinfo_init_resources(int generation)
}
/*
+ * Free an individual dev.
+ */
+static void
+devinfo_free_dev(struct devinfo_i_dev *dd)
+{
+ free(dd->dd_name);
+ free(dd->dd_desc);
+ free(dd->dd_drivername);
+ free(dd->dd_pnpinfo);
+ free(dd->dd_location);
+ free(dd);
+}
+
+/*
* Free the list contents.
*/
void
@@ -376,12 +395,7 @@ devinfo_free(void)
while ((dd = TAILQ_FIRST(&devinfo_dev)) != NULL) {
TAILQ_REMOVE(&devinfo_dev, dd, dd_link);
- free(dd->dd_name);
- free(dd->dd_desc);
- free(dd->dd_drivername);
- free(dd->dd_pnpinfo);
- free(dd->dd_location);
- free(dd);
+ devinfo_free_dev(dd);
}
while ((dm = TAILQ_FIRST(&devinfo_rman)) != NULL) {
TAILQ_REMOVE(&devinfo_rman, dm, dm_link);