Date: Tue, 4 Aug 2020 21:05:53 +0000 (UTC) From: Eric van Gyzen <vangyzen@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r363866 - head/lib/libdevinfo Message-ID: <202008042105.074L5rIh053400@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: vangyzen Date: Tue Aug 4 21:05:53 2020 New Revision: 363866 URL: https://svnweb.freebsd.org/changeset/base/363866 Log: 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 Modified: head/lib/libdevinfo/devinfo.c Modified: head/lib/libdevinfo/devinfo.c ============================================================================== --- head/lib/libdevinfo/devinfo.c Tue Aug 4 20:54:12 2020 (r363865) +++ head/lib/libdevinfo/devinfo.c Tue Aug 4 21:05:53 2020 (r363866) @@ -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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202008042105.074L5rIh053400>