From: Stephen Smalley <sds@epoch.ncsc.mil>

This patch fixes several bugs in the error handling code for SELinux policy
loading that were introduced by my earlier patch to eliminate unaligned
accesses by that code.

Signed-off-by:  Stephen Smalley <sds@epoch.ncsc.mil>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/security/selinux/ss/avtab.c    |    4 +++-
 25-akpm/security/selinux/ss/ebitmap.c  |    6 ++++--
 25-akpm/security/selinux/ss/policydb.c |    9 +++++++--
 3 files changed, 14 insertions(+), 5 deletions(-)

diff -puN security/selinux/ss/avtab.c~selinux-fix-error-handling-code-for-policy-load security/selinux/ss/avtab.c
--- 25/security/selinux/ss/avtab.c~selinux-fix-error-handling-code-for-policy-load	Thu Jan 13 16:10:01 2005
+++ 25-akpm/security/selinux/ss/avtab.c	Thu Jan 13 16:10:01 2005
@@ -386,8 +386,10 @@ int avtab_read(struct avtab *a, void *fp
 		goto bad;
 	}
 	for (i = 0; i < nel; i++) {
-		if (avtab_read_item(fp, &avdatum, &avkey))
+		if (avtab_read_item(fp, &avdatum, &avkey)) {
+			rc = -EINVAL;
 			goto bad;
+		}
 		rc = avtab_insert(a, &avkey, &avdatum);
 		if (rc) {
 			if (rc == -ENOMEM)
diff -puN security/selinux/ss/ebitmap.c~selinux-fix-error-handling-code-for-policy-load security/selinux/ss/ebitmap.c
--- 25/security/selinux/ss/ebitmap.c~selinux-fix-error-handling-code-for-policy-load	Thu Jan 13 16:10:01 2005
+++ 25-akpm/security/selinux/ss/ebitmap.c	Thu Jan 13 16:10:01 2005
@@ -237,7 +237,7 @@ void ebitmap_destroy(struct ebitmap *e)
 
 int ebitmap_read(struct ebitmap *e, void *fp)
 {
-	int rc = -EINVAL;
+	int rc;
 	struct ebitmap_node *n, *l;
 	u32 buf[3], mapsize, count, i;
 	u64 map;
@@ -256,7 +256,7 @@ int ebitmap_read(struct ebitmap *e, void
 		printk(KERN_ERR "security: ebitmap: map size %u does not "
 		       "match my size %Zd (high bit was %d)\n", mapsize,
 		       MAPSIZE, e->highbit);
-		goto out;
+		goto bad;
 	}
 	if (!e->highbit) {
 		e->node = NULL;
@@ -329,6 +329,8 @@ out:
 bad_free:
 	kfree(n);
 bad:
+	if (!rc)
+		rc = -EINVAL;
 	ebitmap_destroy(e);
 	goto out;
 }
diff -puN security/selinux/ss/policydb.c~selinux-fix-error-handling-code-for-policy-load security/selinux/ss/policydb.c
--- 25/security/selinux/ss/policydb.c~selinux-fix-error-handling-code-for-policy-load	Thu Jan 13 16:10:01 2005
+++ 25-akpm/security/selinux/ss/policydb.c	Thu Jan 13 16:10:01 2005
@@ -832,7 +832,6 @@ static int class_read(struct policydb *p
 	}
 
 	lc = NULL;
-	rc = -EINVAL;
 	for (i = 0; i < ncons; i++) {
 		c = kmalloc(sizeof(*c), GFP_KERNEL);
 		if (!c) {
@@ -875,6 +874,7 @@ static int class_read(struct policydb *p
 			e->attr = le32_to_cpu(buf[1]);
 			e->op = le32_to_cpu(buf[2]);
 
+			rc = -EINVAL;
 			switch (e->expr_type) {
 			case CEXPR_NOT:
 				if (depth < 0)
@@ -915,6 +915,8 @@ static int class_read(struct policydb *p
 	rc = hashtab_insert(h, key, cladatum);
 	if (rc)
 		goto bad;
+
+	rc = 0;
 out:
 	return rc;
 bad:
@@ -1110,7 +1112,6 @@ int policydb_read(struct policydb *p, vo
 	if (rc)
 		goto out;
 
-	rc = -EINVAL;
 	/* Read the magic number and string length. */
 	rc = next_entry(buf, fp, sizeof(u32)* 2);
 	if (rc < 0)
@@ -1503,12 +1504,16 @@ int policydb_read(struct policydb *p, vo
 	rc = mls_read_trusted(p, fp);
 	if (rc)
 		goto bad;
+	
+	rc = 0;
 out:
 	policydb_loaded_version = r_policyvers;
 	return rc;
 bad_newc:
 	ocontext_destroy(newc,OCON_FSUSE);
 bad:
+	if (!rc)
+		rc = -EINVAL;
 	policydb_destroy(p);
 	goto out;
 }
_