diff mbox

[ndctl,2/2] ndctl: fix various memory leaks reported by valgrind

Message ID 1440545834-10559-3-git-send-email-vishal.l.verma@intel.com (mailing list archive)
State Accepted
Commit 6ce61e0e7974
Headers show

Commit Message

Verma, Vishal L Aug. 25, 2015, 11:37 p.m. UTC
Fix the following classes of leaks/warnings:
- Properly free strings etc allocated in namespace/btt/dimm.. etc. data
  structures
- Fix realloc usage: instead of ptr = realloc(ptr, ...), use a temp
  variable so that we don't lose the last reference to the original ptr
  in case of a realloc error.
- Fix ndctl_unref to also drop the kmod reference to mirror ndctl_new.
- Fix a warning for an if condition on a potentially uninitialized
  variable.

Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
 lib/libndctl.c      | 23 +++++++++++++++++++++--
 lib/test-libndctl.c | 13 ++++++++-----
 2 files changed, 29 insertions(+), 7 deletions(-)
diff mbox

Patch

diff --git a/lib/libndctl.c b/lib/libndctl.c
index 0b558df..f14e87c 100644
--- a/lib/libndctl.c
+++ b/lib/libndctl.c
@@ -502,9 +502,11 @@  static void free_namespace(struct ndctl_namespace *ndns, struct list_head *head)
 {
 	if (head)
 		list_del_from(head, &ndns->list);
+	free(ndns->lbasize.supported);
 	free(ndns->ndns_path);
 	free(ndns->ndns_buf);
 	free(ndns->bdev);
+	free(ndns->alt_name);
 	kmod_module_unref(ndns->module);
 	free(ndns);
 }
@@ -533,6 +535,7 @@  static void free_btt(struct ndctl_btt *btt, struct list_head *head)
 	free(btt->lbasize.supported);
 	free(btt->btt_path);
 	free(btt->btt_buf);
+	free(btt->bdev);
 	free(btt);
 }
 
@@ -579,6 +582,8 @@  static void free_bus(struct ndctl_bus *bus)
 
 	list_for_each_safe(&bus->dimms, dimm, _d, list) {
 		list_del_from(&bus->dimms, &dimm->list);
+		free(dimm->dimm_path);
+		free(dimm->dimm_buf);
 		free(dimm);
 	}
 	list_for_each_safe(&bus->regions, region, _r, list)
@@ -586,6 +591,7 @@  static void free_bus(struct ndctl_bus *bus)
 	list_del_from(&bus->ctx->busses, &bus->list);
 	free(bus->provider);
 	free(bus->bus_path);
+	free(bus->bus_buf);
 	free(bus->wait_probe_path);
 	free(bus);
 }
@@ -615,6 +621,7 @@  NDCTL_EXPORT struct ndctl_ctx *ndctl_unref(struct ndctl_ctx *ctx)
 		return NULL;
 	udev_queue_unref(ctx->udev_queue);
 	udev_unref(ctx->udev);
+	kmod_unref(ctx->kmod_ctx);
 	info(ctx, "context %p released\n", ctx);
 	free_context(ctx);
 	return NULL;
@@ -919,6 +926,7 @@  static int add_bus(void *parent, int id, const char *ctl_base)
  err_dev_path:
  err_read:
 	free(bus->provider);
+	free(bus->bus_buf);
 	free(bus);
  out:
  err_bus:
@@ -1214,6 +1222,8 @@  static int add_dimm(void *parent, int id, const char *dimm_base)
 	return 0;
 
  err_read:
+	free(dimm->dimm_buf);
+	free(dimm->dimm_path);
 	free(dimm);
  err_dimm:
 	free(path);
@@ -2844,6 +2854,7 @@  static int add_namespace(void *parent, int id, const char *ndns_base)
 	ndctl_namespace_foreach(region, ndns_dup)
 		if (ndns_dup->id == ndns->id) {
 			free_namespace(ndns, NULL);
+			free(path);
 			return 1;
 		}
 
@@ -2854,6 +2865,7 @@  static int add_namespace(void *parent, int id, const char *ndns_base)
  err_read:
 	free(ndns->ndns_buf);
 	free(ndns->ndns_path);
+	free(ndns->alt_name);
 	free(ndns);
  err_namespace:
 	free(path);
@@ -3326,8 +3338,10 @@  NDCTL_EXPORT int ndctl_namespace_set_alt_name(struct ndctl_namespace *ndns,
 	if (!buf)
 		return -ENOMEM;
 
-	if (sysfs_write_attr(ctx, path, buf) < 0)
+	if (sysfs_write_attr(ctx, path, buf) < 0) {
+		free(buf);
 		return -ENXIO;
+	}
 
 	free(ndns->alt_name);
 	ndns->alt_name = buf;
@@ -3425,6 +3439,7 @@  static int parse_lbasize_supported(struct ndctl_ctx *ctx, const char *devname,
 		const char *buf, struct ndctl_lbasize *lba)
 {
 	char *s = strdup(buf), *end, *field;
+	void *temp;
 
 	if (!s)
 		return -ENOMEM;
@@ -3448,8 +3463,12 @@  static int parse_lbasize_supported(struct ndctl_ctx *ctx, const char *devname,
 			break;
 		}
 
-		lba->supported = realloc(lba->supported,
+		temp = realloc(lba->supported,
 				sizeof(unsigned int) * ++lba->num);
+		if (temp != NULL)
+			lba->supported = temp;
+		else
+			goto err;
 		lba->supported[lba->num - 1] = val;
 		field = end + 1;
 		end = strchr(field, ' ');
diff --git a/lib/test-libndctl.c b/lib/test-libndctl.c
index a33e4db..c2e7bc7 100644
--- a/lib/test-libndctl.c
+++ b/lib/test-libndctl.c
@@ -768,7 +768,7 @@  static int check_namespaces(struct ndctl_region *region,
 	struct ndctl_namespace **ndns_save;
 	struct namespace *namespace;
 	int i, j, rc, retry_cnt = 1;
-	void *buf = NULL;
+	void *buf = NULL, *__ndns_save;
 	char devname[50];
 
 	if (!region)
@@ -977,15 +977,17 @@  static int check_namespaces(struct ndctl_region *region,
 			close(fd);
 		namespace->do_configure = 0;
 
-		ndns_save = realloc(ndns_save,
+		__ndns_save = realloc(ndns_save,
 				sizeof(struct ndctl_namespace *) * (i + 1));
-		if (!ndns_save) {
+		if (!__ndns_save) {
 			fprintf(stderr, "%s: %s() -ENOMEM\n",
 					devname, __func__);
 			rc = -ENOMEM;
 			break;
+		} else {
+			ndns_save = __ndns_save;
+			ndns_save[i] = ndns;
 		}
-		ndns_save[i] = ndns;
 
 		if (rc)
 			break;
@@ -1005,6 +1007,7 @@  static int check_namespaces(struct ndctl_region *region,
 	 */
 	if (retry_cnt--) {
 		ndctl_region_enable(region);
+		free(ndns_save);
 		goto retry;
 	}
 
@@ -1380,7 +1383,7 @@  static int check_commands(struct ndctl_bus *bus, struct ndctl_dimm *dimm,
 		[ND_CMD_ARS_START] = { check_ars_start },
 		[ND_CMD_ARS_STATUS] = { check_ars_status },
 	};
-	unsigned int i, rc;
+	unsigned int i, rc = 0;
 
 	/* Check DIMM commands */
 	check_cmds = __check_dimm_cmds;