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
This commit is contained in:
parent
b64dca2b6f
commit
32592d86df
@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
static int devinfo_init_devices(int generation);
|
static int devinfo_init_devices(int generation);
|
||||||
static int devinfo_init_resources(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_dev) devinfo_dev;
|
||||||
TAILQ_HEAD(,devinfo_i_rman) devinfo_rman;
|
TAILQ_HEAD(,devinfo_i_rman) devinfo_rman;
|
||||||
@ -225,7 +226,7 @@ devinfo_init_devices(int generation)
|
|||||||
rlen, sizeof(udev));
|
rlen, sizeof(udev));
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
if ((dd = malloc(sizeof(*dd))) == NULL)
|
if ((dd = calloc(1, sizeof(*dd))) == NULL)
|
||||||
return(ENOMEM);
|
return(ENOMEM);
|
||||||
dd->dd_dev.dd_handle = udev.dv_handle;
|
dd->dd_dev.dd_handle = udev.dv_handle;
|
||||||
dd->dd_dev.dd_parent = udev.dv_parent;
|
dd->dd_dev.dd_parent = udev.dv_parent;
|
||||||
@ -242,10 +243,14 @@ devinfo_init_devices(int generation)
|
|||||||
dd->dd_location = NULL;
|
dd->dd_location = NULL;
|
||||||
#define UNPACK(x) \
|
#define UNPACK(x) \
|
||||||
dd->dd_dev.x = dd->x = strdup(walker); \
|
dd->dd_dev.x = dd->x = strdup(walker); \
|
||||||
if (dd->x == NULL) \
|
if (dd->x == NULL) { \
|
||||||
|
devinfo_free_dev(dd); \
|
||||||
return(ENOMEM); \
|
return(ENOMEM); \
|
||||||
if (walker + strnlen(walker, ep - walker) >= ep) \
|
} \
|
||||||
|
if (walker + strnlen(walker, ep - walker) >= ep) { \
|
||||||
|
devinfo_free_dev(dd); \
|
||||||
return(EINVAL); \
|
return(EINVAL); \
|
||||||
|
} \
|
||||||
walker += strlen(walker) + 1;
|
walker += strlen(walker) + 1;
|
||||||
|
|
||||||
UNPACK(dd_name);
|
UNPACK(dd_name);
|
||||||
@ -364,6 +369,20 @@ devinfo_init_resources(int generation)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
* Free the list contents.
|
||||||
*/
|
*/
|
||||||
@ -376,12 +395,7 @@ devinfo_free(void)
|
|||||||
|
|
||||||
while ((dd = TAILQ_FIRST(&devinfo_dev)) != NULL) {
|
while ((dd = TAILQ_FIRST(&devinfo_dev)) != NULL) {
|
||||||
TAILQ_REMOVE(&devinfo_dev, dd, dd_link);
|
TAILQ_REMOVE(&devinfo_dev, dd, dd_link);
|
||||||
free(dd->dd_name);
|
devinfo_free_dev(dd);
|
||||||
free(dd->dd_desc);
|
|
||||||
free(dd->dd_drivername);
|
|
||||||
free(dd->dd_pnpinfo);
|
|
||||||
free(dd->dd_location);
|
|
||||||
free(dd);
|
|
||||||
}
|
}
|
||||||
while ((dm = TAILQ_FIRST(&devinfo_rman)) != NULL) {
|
while ((dm = TAILQ_FIRST(&devinfo_rman)) != NULL) {
|
||||||
TAILQ_REMOVE(&devinfo_rman, dm, dm_link);
|
TAILQ_REMOVE(&devinfo_rman, dm, dm_link);
|
||||||
|
Loading…
Reference in New Issue
Block a user