Hello,

This is for external/libsepol.

Attached you will find the Klocwork report on external/libsepol and my fix in a 
patch. The change is done on master branch.
Some of the Klocwork findings are, I think, false positive. I keep them in the 
report so that you can go over one more time.
Please review my change and let me know any additional correction I should make.

Thank you very much for the feedback.

Regards,
Alice Chu

Attachment: kw_libsepol.xlsx
Description: kw_libsepol.xlsx

From ed1d11cee2692e76a2a80158ae0a0010e3d0851a Mon Sep 17 00:00:00 2001
From: Alice Chu <alice....@sta.samsung.com>
Date: Fri, 21 Dec 2012 15:24:43 -0800
Subject: [PATCH] Fix issues found by Klocwork

Change-Id: I2182f9297573a4f0af86383957e9925bbee97c44
---
 src/expand.c           |   17 ++++++++++++++++-
 src/genusers.c         |   11 ++++++++++-
 src/hierarchy.c        |    1 +
 src/link.c             |    7 ++++++-
 src/nodes.c            |    1 +
 src/policydb.c         |    6 ++++--
 src/policydb_convert.c |    1 +
 src/services.c         |    2 ++
 src/write.c            |    1 +
 9 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/src/expand.c b/src/expand.c
index 2003eb6..e4ca316 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -226,7 +226,7 @@ static int common_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
 {
 	int ret;
 	char *id, *new_id;
-	common_datum_t *common, *new_common;
+	common_datum_t *common, *new_common = NULL;
 	expand_state_t *state;
 
 	id = (char *)key;
@@ -251,6 +251,9 @@ static int common_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
 	new_id = strdup(id);
 	if (!new_id) {
 		ERR(state->handle, "Out of memory!");
+		// free memory created by symtab_init first, then free new_common
+		if (new_common)
+			hashtab_destroy(new_common->permissions.table);
 		free(new_common);
 		return -1;
 	}
@@ -263,6 +266,9 @@ static int common_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
 			   (hashtab_datum_t *) new_common);
 	if (ret) {
 		ERR(state->handle, "hashtab overflow");
+		// free memory created by symtab_init first, then free new_common
+		if (new_common)
+			hashtab_destroy(new_common->permissions.table);
 		free(new_common);
 		free(new_id);
 		return -1;
@@ -812,6 +818,7 @@ static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
 		new_id = strdup(id);
 		if (!new_id) {
 			ERR(state->handle, "Out of memory!");
+			free(new_role);
 			return -1;
 		}
 
@@ -963,6 +970,7 @@ static int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
 		new_id = strdup(id);
 		if (!new_id) {
 			ERR(state->handle, "Out of memory!");
+			free(new_user);
 			return -1;
 		}
 		ret = hashtab_insert(state->out->p_users.table,
@@ -1982,6 +1990,7 @@ static int cond_node_copy(expand_state_t * state, cond_node_t * cn)
 
 	if (cond_node_map_bools(state, tmp)) {
 		ERR(state->handle, "Error mapping booleans");
+		free(tmp);
 		return -1;
 	}
 
@@ -2189,6 +2198,7 @@ static int genfs_copy(expand_state_t * state)
 		newgenfs->fstype = strdup(genfs->fstype);
 		if (!newgenfs->fstype) {
 			ERR(state->handle, "Out of memory!");
+			free(newgenfs);
 			return -1;
 		}
 
@@ -2197,12 +2207,17 @@ static int genfs_copy(expand_state_t * state)
 			newc = malloc(sizeof(ocontext_t));
 			if (!newc) {
 				ERR(state->handle, "Out of memory!");
+				free(newgenfs->fstype);
+				free(newgenfs);
 				return -1;
 			}
 			memset(newc, 0, sizeof(ocontext_t));
 			newc->u.name = strdup(c->u.name);
 			if (!newc->u.name) {
 				ERR(state->handle, "Out of memory!");
+				free(newc);
+				free(newgenfs->fstype);
+				free(newgenfs);
 				return -1;
 			}
 			newc->v.sclass = c->v.sclass;
diff --git a/src/genusers.c b/src/genusers.c
index 37528e2..a31ea08 100644
--- a/src/genusers.c
+++ b/src/genusers.c
@@ -91,13 +91,20 @@ static int load_users(struct policydb *policydb, const char *path)
 			ebitmap_init(&usrdatum->roles.roles);
 		} else {
 			char *id = strdup(q);
+			if (!id) {
+				ERR(NULL, "out of memory");
+				free(buffer);
+				fclose(fp);
+				return -1;
+			}
 
 			/* Adding a new user definition. */
 			usrdatum =
 			    (user_datum_t *) malloc(sizeof(user_datum_t));
-			if (!id || !usrdatum) {
+			if (!usrdatum) {
 				ERR(NULL, "out of memory");
 				free(buffer);
+				free(id);
 				fclose(fp);
 				return -1;
 			}
@@ -108,6 +115,8 @@ static int load_users(struct policydb *policydb, const char *path)
 					   id, (hashtab_datum_t) usrdatum)) {
 				ERR(NULL, "out of memory");
 				free(buffer);
+				free(id);
+				free(usrdatum);
 				fclose(fp);
 				return -1;
 			}
diff --git a/src/hierarchy.c b/src/hierarchy.c
index e2df5a4..d787a64 100644
--- a/src/hierarchy.c
+++ b/src/hierarchy.c
@@ -360,6 +360,7 @@ static int check_cond_avtab_hierarchy(cond_list_t * cond_list,
 				args->numerr++;
 		}
 		cond_av_list_destroy(expl);
+		avtab_destroy(&expa);
 
 		/*
 		 * Check false condition
diff --git a/src/link.c b/src/link.c
index 01d3231..d36b103 100644
--- a/src/link.c
+++ b/src/link.c
@@ -329,6 +329,8 @@ static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
 
 	return 0;
       err:
+	if (new_class)
+		hashtab_destroy(new_class->permissions.table);
 	free(new_class);
 	free(new_id);
 	return ret;
@@ -1301,7 +1303,8 @@ static int copy_avrule_list(avrule_t * list, avrule_t ** dst,
 			if (new_rule->perms == NULL) {
 				new_rule->perms = new_perm;
 			} else {
-				tail_perm->next = new_perm;
+				if (tail_perm) /* make sure no dereferencing of NULL pointer*/
+					tail_perm->next = new_perm;
 			}
 			tail_perm = new_perm;
 			cur_perm = cur_perm->next;
@@ -1765,6 +1768,7 @@ static int copy_avrule_block(link_state_t * state, policy_module_t * module,
 			new_decl->module_name = strdup(module->policy->name);
 			if (new_decl->module_name == NULL) {
 				ERR(state->handle, "Out of memory\n");
+				avrule_decl_destroy(new_decl);
 				ret = -1;
 				goto cleanup;
 			}
@@ -1784,6 +1788,7 @@ static int copy_avrule_block(link_state_t * state, policy_module_t * module,
 
 		ret = copy_avrule_decl(state, module, decl, new_decl);
 		if (ret) {
+			avrule_decl_destroy(new_decl);
 			goto cleanup;
 		}
 
diff --git a/src/nodes.c b/src/nodes.c
index ebf5f1d..b7695fb 100644
--- a/src/nodes.c
+++ b/src/nodes.c
@@ -282,6 +282,7 @@ int sepol_node_query(sepol_handle_t * handle,
 		ERR(handle, "unsupported protocol %u", proto);
 		goto err;
 	}
+        sepol_node_free(*response);
 	*response = NULL;
 	return STATUS_SUCCESS;
 
diff --git a/src/policydb.c b/src/policydb.c
index ff292f6..fd9b57b 100644
--- a/src/policydb.c
+++ b/src/policydb.c
@@ -3448,7 +3448,8 @@ static int avrule_block_read(policydb_t * p,
 			if (curblock->branch_list == NULL) {
 				curblock->branch_list = curdecl;
 			} else {
-				last_decl->next = curdecl;
+				if (last_decl != NULL)
+					last_decl->next = curdecl;
 			}
 			last_decl = curdecl;
 			num_decls--;
@@ -3457,7 +3458,8 @@ static int avrule_block_read(policydb_t * p,
 		if (*block == NULL) {
 			*block = curblock;
 		} else {
-			last_block->next = curblock;
+			if (last_block != NULL)
+				last_block->next = curblock;
 		}
 		last_block = curblock;
 
diff --git a/src/policydb_convert.c b/src/policydb_convert.c
index 32832bb..3fc40cb 100644
--- a/src/policydb_convert.c
+++ b/src/policydb_convert.c
@@ -20,6 +20,7 @@ int policydb_from_image(sepol_handle_t * handle,
 	pf.handle = handle;
 
 	if (policydb_read(policydb, &pf, 0)) {
+		policydb_destroy(policydb);
 		ERR(handle, "policy image is invalid");
 		errno = EINVAL;
 		return STATUS_ERR;
diff --git a/src/services.c b/src/services.c
index 9c2920c..bed1e9b 100644
--- a/src/services.c
+++ b/src/services.c
@@ -96,6 +96,7 @@ int sepol_set_policydb_from_file(FILE * fp)
 		return -1;
 	}
 	if (policydb_read(&mypolicydb, &pf, 0)) {
+		policydb_destroy(&mypolicydb);
 		ERR(NULL, "can't read binary policy: %s", strerror(errno));
 		return -1;
 	}
@@ -1016,6 +1017,7 @@ int hidden sepol_load_policy(void *data, size_t len)
 		return -ENOMEM;
 
 	if (policydb_read(&newpolicydb, fp, 1)) {
+		policydb_destroy(&newpolicydb);
 		return -EINVAL;
 	}
 
diff --git a/src/write.c b/src/write.c
index 22e6143..ab1c257 100644
--- a/src/write.c
+++ b/src/write.c
@@ -1810,6 +1810,7 @@ static int scope_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
 	buf[0] = cpu_to_le32(key_len);
 	if (put_entry(buf, sizeof(*buf), 1, fp) != 1 ||
 	    put_entry(key, 1, key_len, fp) != key_len) {
+		free(dyn_buf);
 		return POLICYDB_ERROR;
 	}
 	buf[0] = cpu_to_le32(scope->scope);
-- 
1.7.0.4

Reply via email to