[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/4] features/fixes for rawhide and refpolicy


libsepol changes:

bug fix for null dereference in expander
module package format changed (sectioned and versioned)

Joshua Brindle
diff -purN -x .svn libsepol/src/expand.c libsepol/src/expand.c
--- libsepol/src/expand.c	2005-10-20 14:28:24.000000000 -0400
+++ libsepol/src/expand.c	2005-10-22 18:00:04.000000000 -0400
@@ -1563,7 +1563,8 @@ int type_set_expand(type_set_t *set, ebi
         ebitmap_init(&neg_types);
 	ebitmap_for_each_bit(&set->negset, tnode, i) {
                 if (ebitmap_node_get_bit(tnode, i)) {
-                        if (p->type_val_to_struct[i]->isattr) {
+                        if (p->type_val_to_struct[i] && 
+			    p->type_val_to_struct[i]->isattr) {
                                 if (ebitmap_union(&neg_types, &p->type_val_to_struct[i]->types)) {
                                         return -1;
                                 }
@@ -1580,7 +1581,8 @@ int type_set_expand(type_set_t *set, ebi
                 for (i = 0; i < p->p_types.nprim; i++) {
                         if (ebitmap_get_bit(&neg_types, i))
                                 continue;
-                        if (p->type_val_to_struct[i]->isattr)
+                        if (p->type_val_to_struct[i] &&
+			    p->type_val_to_struct[i]->isattr)
                                 continue;
                         if (ebitmap_set_bit(t, i, 1))
                                 return -1;
@@ -1596,7 +1598,8 @@ int type_set_expand(type_set_t *set, ebi
 
         if (set->flags & TYPE_COMP) {
                 for(i = 0; i < p->p_types.nprim; i++) {
-                        if (p->type_val_to_struct[i]->isattr) {
+                        if (p->type_val_to_struct[i] &&
+			    p->type_val_to_struct[i]->isattr) {
                                 assert(!ebitmap_get_bit(t, i));
                                 continue;
                         }
diff -purN -x .svn libsepol/src/module.c libsepol/src/module.c
--- libsepol/src/module.c	2005-10-20 14:28:24.000000000 -0400
+++ libsepol/src/module.c	2005-10-24 08:12:26.000000000 -0400
@@ -18,6 +18,7 @@
  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+
 #include <sepol/policydb/link.h>
 #include <sepol/policydb/expand.h>
 #include <sepol/policydb/module.h>
@@ -27,11 +28,52 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#define SEPOL_PACKAGE_SECTION_FC 0xf97cff90
+
+static int policy_file_seek(struct policy_file *fp, long offset) 
+{
+	switch (fp->type) {
+	case PF_USE_STDIO:
+		return fseek(fp->fp, offset, SEEK_SET);
+	case PF_USE_MEMORY:
+		if (offset > fp->size) {
+			errno = EFAULT;
+			return -1;
+		}
+		fp->data -= fp->size - fp->len;
+		fp->data += offset; 
+		fp->len = fp->size - offset;
+		return 0;	
+	default:
+		return 0;		 
+	}
+}
+
+static size_t policy_file_length(struct policy_file *fp)
+{
+	long prev_offset, end_offset;
+	switch (fp->type) {
+	case PF_USE_STDIO:
+		prev_offset = ftell(fp->fp);
+		fseek(fp->fp, 0L, SEEK_END);
+		end_offset = ftell(fp->fp);
+		fseek(fp->fp, prev_offset, SEEK_SET);
+		return end_offset;
+	case PF_USE_MEMORY:
+		return fp->size;
+	default:
+		return 0;
+	}
+}
+			
 int sepol_module_package_init(sepol_module_package_t *p)
 {
 	memset(p, 0, sizeof(sepol_module_package_t));
 	if (sepol_policydb_create(&p->policy))
 		return -1;
+
+	p->num_sections = 0;
+	p->version = 1;
 	return 0;
 }
 
@@ -181,159 +223,245 @@ static int read_helper(char *buf, struct
 	return 0;
 }
 
-int sepol_module_package_read(sepol_module_package_t *mod, 
-			      struct sepol_policy_file *spf, int verbose)
+/* Get the section offsets from a package file, offsets will be malloc'd to
+ * the appropriate size and the caller must free() them */
+static int sepol_module_package_read_offsets(sepol_module_package_t *mod, 
+				struct policy_file *file, long **offsets)
 {
-	struct policy_file *file= &spf->pf;
 	uint32_t *buf;
-        int retval;
+	int i;
 
-	buf = next_entry(file, sizeof(uint32_t) * 2);
+	buf = next_entry(file, sizeof(uint32_t) * 3);
 	if (!buf)
 		return -1;
 	if (le32_to_cpu(buf[0]) != SEPOL_MODULE_PACKAGE_MAGIC) {
 		return -1;	
 	}
-	mod->file_contexts_len = le32_to_cpu(buf[1]);
 	
-	if (mod->file_contexts_len) {		
-		mod->file_contexts = (char *)malloc(mod->file_contexts_len);
-		if (!mod->file_contexts) {
-			return -1;	
+	mod->version = le32_to_cpu(buf[1]);
+	mod->num_sections = le32_to_cpu(buf[2]);
+
+	*offsets = (long *)malloc((mod->num_sections + 1) * sizeof(long));
+	if (!*offsets)
+		return -1;
+
+	buf = next_entry(file, sizeof(uint32_t) * mod->num_sections);
+	if (!buf)
+		return -1;
+
+	for (i = 0; i < mod->num_sections; i++)
+		(*offsets)[i] = buf[i];
+
+	(*offsets)[mod->num_sections] = policy_file_length(file);
+	return 0;
+}
+
+int sepol_module_package_read(sepol_module_package_t *mod, 
+			      struct sepol_policy_file *spf, int verbose)
+{
+	struct policy_file *file= &spf->pf;
+	uint32_t *buf;
+	long *offsets;
+	size_t len;
+        int retval = -1, i;
+
+
+	if (sepol_module_package_read_offsets(mod, file, &offsets))
+		return -1;
+
+	/* we know the section offsets, seek to them and read in the data */
+
+	for (i = 0; i < mod->num_sections; i++ ) {
+	
+		if (policy_file_seek(file, offsets[i]))
+			goto cleanup;
+
+		len = offsets[i + 1] - offsets[i];
+
+		/* read the magic number, so that we know which function to call */
+		buf = next_entry(file, sizeof(uint32_t));
+		if (!buf)
+			goto cleanup;
+
+		switch(buf[0]) {
+		case SEPOL_PACKAGE_SECTION_FC:
+			mod->file_contexts_len = len - 4;
+			mod->file_contexts = (char *)malloc(len);
+			if (!mod->file_contexts) {
+				goto cleanup;
+			}
+			if (read_helper(mod->file_contexts, file, mod->file_contexts_len)) {
+                        	free(mod->file_contexts);
+	                        mod->file_contexts = NULL;
+				goto cleanup;
+        	        }
+			break;
+		case POLICYDB_MOD_MAGIC:
+			/* seek back to where the magic number was */
+			if (policy_file_seek(file, offsets[i])) 
+				goto cleanup;
+
+			retval = policydb_read(&mod->policy->p, file, verbose);
+		        if (retval < 0) {
+		                /* don't destroy the policy -- policydb did that already */
+		                free(mod->policy);
+		                mod->policy = NULL;
+		        }
+			break;
+		default:
+			/* unknown section, ignore */	
+			break;
 		}
-		if (read_helper(mod->file_contexts, file, mod->file_contexts_len)) {
-                        free(mod->file_contexts);
-                        mod->file_contexts = NULL;
-			return -1;
-                }
 	}
 
-	retval = policydb_read(&mod->policy->p, file, verbose);
-        if (retval < 0) {
-                /* don't destroy the policy -- policydb did that already */
-                free(mod->policy);
-                mod->policy = NULL;
-        }
+	free(offsets);
+	return 0;
 
+cleanup:
+	free(offsets);
         return retval;
 }
 
 int sepol_module_package_info(struct sepol_policy_file *spf, int *type, char **name, char **version)
 {
 	struct policy_file *file = &spf->pf;
-	uint32_t *buf, *buf2, len;
+	sepol_module_package_t *mod;
+	uint32_t *buf, len;
+	long *offsets;
+	int i;
 
-	buf = next_entry(file, sizeof(uint32_t) * 2);
-	if (!buf)
+	if (sepol_module_package_create(&mod))
 		return -1;
-	if (le32_to_cpu(buf[0]) != SEPOL_MODULE_PACKAGE_MAGIC) {
-		return -1;	
-	}
-	
-	/* skip file contexts */
-	len = le32_to_cpu(buf[1]);
-	if (len) {
-		buf2 = malloc(len);
-		if (!buf2) {
-			return -1;	
-		}
-		if (read_helper((char*)buf2, file, len)) {
-                        free(buf2);
-			return -1;
-                }
-		free(buf2);
-	}
-	
-	buf = next_entry(file, sizeof(uint32_t)* 2);
-	if (!buf) {
-		return -1;
-	}
-        if (le32_to_cpu(buf[0]) != POLICYDB_MOD_MAGIC) {
-                return -1;
-        }
 
-	len = le32_to_cpu(buf[1]);
-	if (len != strlen(POLICYDB_MOD_STRING)) {
+	if (sepol_module_package_read_offsets(mod, file, &offsets))
 		return -1;
-	}
+
+	for (i = 0; i < mod->num_sections; i++ ) {
 	
-	/* skip id */
-	buf = next_entry(file, len);
-	if (!buf) {
-		return -1;
-	}
+		if (policy_file_seek(file, offsets[i]))
+			goto cleanup;
+
+		len = offsets[i + 1] - offsets[i];
+
+		/* read the magic number, so that we know which function to call */
+		buf = next_entry(file, sizeof(uint32_t) * 2);
+		if (!buf)
+			goto cleanup;
+
+		switch(buf[0]) {
+		case SEPOL_PACKAGE_SECTION_FC:
+		/* skip file contexts */
+			break;
+		case POLICYDB_MOD_MAGIC:
+			len = le32_to_cpu(buf[1]);
+			if (len != strlen(POLICYDB_MOD_STRING)) {
+				goto cleanup;
+			}
 	
-	buf = next_entry(file, sizeof(uint32_t)* 5);
-	if (!buf)
-		return -1;
+			/* skip id */
+			buf = next_entry(file, len);
+			if (!buf) {
+				goto cleanup;
+			}
 	
-	*type = le32_to_cpu(buf[0]);
-	/* if base - we're done */
-	if (*type == POLICY_BASE) {
-		*name = NULL;
-		*version = NULL;
-		return 0;
-	} else if (*type != POLICY_MOD) {
-		return -1;	
-	}
+			buf = next_entry(file, sizeof(uint32_t)* 5);
+			if (!buf)
+				goto cleanup;
 	
-	/* read the name and version */
-	buf = next_entry(file, sizeof(uint32_t));
-        if (!buf)
-                return -1;
-        len = le32_to_cpu(buf[0]);
-        buf = next_entry(file, len);
-        if (!buf)
-                return -1;
-        *name = malloc(len + 1);
-        if (!*name) {
-                return -1;
-        }
-        memcpy(*name, buf, len);
-        (*name)[len] = '\0';
-        buf = next_entry(file, sizeof(uint32_t));
-        if (!buf)
-                return -1;
-        len = le32_to_cpu(buf[0]);
-        buf = next_entry(file, len);
-        if (!buf)
-                return -1;
-        *version = malloc(len + 1);
-        if (!*version)
-                return -1;
-        memcpy(*version, buf, len);
-        (*version)[len] = '\0';
+			*type = le32_to_cpu(buf[0]);
+			/* if base - we're done */
+			if (*type == POLICY_BASE) {
+				*name = NULL;
+				*version = NULL;
+				return 0;
+			} else if (*type != POLICY_MOD) {
+				goto cleanup;	
+			}
+	
+			/* read the name and version */
+			buf = next_entry(file, sizeof(uint32_t));
+		        if (!buf)
+                		goto cleanup;
+		        len = le32_to_cpu(buf[0]);
+		        buf = next_entry(file, len);
+		        if (!buf)
+		                goto cleanup;
+		        *name = malloc(len + 1);
+		        if (!*name) {
+		                goto cleanup;
+		        }
+		        memcpy(*name, buf, len);
+		        (*name)[len] = '\0';
+		        buf = next_entry(file, sizeof(uint32_t));
+		        if (!buf)
+		                goto cleanup;
+		        len = le32_to_cpu(buf[0]);
+		        buf = next_entry(file, len);
+		        if (!buf)
+		                goto cleanup;
+		        *version = malloc(len + 1);
+		        if (!*version)
+		                goto cleanup;
+		        memcpy(*version, buf, len);
+		        (*version)[len] = '\0';
+			break;
+		default:
+			break;
+		}
+
+	}
+	free(offsets);
 	return 0;
+
+cleanup:
+	free(offsets);
+	return -1;
 }
 
 int sepol_module_package_write(sepol_module_package_t *p, 
 			       struct sepol_policy_file *spf)
 {
 	struct policy_file *file = &spf->pf;
-	uint32_t buf[1], len, len2, index;
+	uint32_t buf[3], offsets[2], len, len2, idx;
 	int rc;
 
+	if (p->policy)
+		p->num_sections++;
+
+	if (p->file_contexts)
+		p->num_sections++;
+
 	buf[0] = cpu_to_le32(SEPOL_MODULE_PACKAGE_MAGIC);
-	if (put_entry(buf, sizeof(uint32_t), 1, file) != 1)
+	buf[1] = cpu_to_le32(p->version);
+	buf[2] = cpu_to_le32(p->num_sections);
+	if (put_entry(buf, sizeof(uint32_t), 3, file) != 3)
 		return -1;
-		
-	buf[0] = cpu_to_le32(p->file_contexts_len);
+
+	/* first section offset (file_contexts) */
+	offsets[0] = (p->num_sections + 3) * sizeof(uint32_t);
+	/* second section (module data) offset is file_contexts + fc_magic_num */	
+	offsets[1] = offsets[0] + sizeof(uint32_t) + p->file_contexts_len;
+	buf[0] = cpu_to_le32(offsets[0]);
+	buf[1] = cpu_to_le32(offsets[1]);
+	if (put_entry(buf, sizeof(uint32_t), 2, file) != 2)
+		return -1;
+	
+	buf[0] = cpu_to_le32(SEPOL_PACKAGE_SECTION_FC);
 	if (put_entry(buf, sizeof(uint32_t), 1, file) != 1)
 		return -1;
-		
+	idx = 0;
 	len = p->file_contexts_len;
-	index = 0;
 	while (len) {
 		if (len > BUFSIZ)
 			len2 = BUFSIZ;
 		else
 			len2 = len;
 
-		if (put_entry(&p->file_contexts[index], 1, len2, file) != len2) {
+		if (put_entry(&p->file_contexts[idx], 1, len2, file) != len2) {
 			return -1;
 		}
 		len -= len2;
-		index += len2;
+		idx += len2;
 	}
 	
 	rc = policydb_write(&p->policy->p, file);
diff -purN -x .svn libsepol/src/policydb_public.c libsepol/src/policydb_public.c
--- libsepol/src/policydb_public.c	2005-10-18 11:07:00.000000000 -0400
+++ libsepol/src/policydb_public.c	2005-10-24 08:12:26.000000000 -0400
@@ -26,6 +26,7 @@ void sepol_policy_file_set_mem(sepol_pol
 	pf->type = PF_USE_MEMORY;
 	pf->data = data;
 	pf->len = len;
+	pf->size = len;
 	return;
 }
 
diff -purN -x .svn libsepol/include/sepol/policydb/module.h libsepol/include/sepol/policydb/module.h
--- libsepol/include/sepol/policydb/module.h	2005-10-20 14:28:01.000000000 -0400
+++ libsepol/include/sepol/policydb/module.h	2005-10-24 08:12:26.000000000 -0400
@@ -28,11 +28,13 @@
 #include <sepol/policydb/policydb.h>
 #include <sepol/policydb/conditional.h>
 
-#define SEPOL_MODULE_PACKAGE_MAGIC 0xf97cff8e
+#define SEPOL_MODULE_PACKAGE_MAGIC 0xf97cff8f
 
 struct sepol_module_package {
 	sepol_policydb_t *policy;
-	char 		*file_contexts;
+	int		 version;
+	int		 num_sections;
+	char 		 *file_contexts;
 	size_t	         file_contexts_len;
 };
 
diff -purN -x .svn libsepol/include/sepol/policydb/policydb.h libsepol/include/sepol/policydb/policydb.h
--- libsepol/include/sepol/policydb/policydb.h	2005-10-20 14:28:01.000000000 -0400
+++ libsepol/include/sepol/policydb/policydb.h	2005-10-24 08:12:26.000000000 -0400
@@ -519,6 +519,7 @@ typedef struct policy_file {
 	unsigned type;
 	char *data;
 	size_t len;
+	size_t size;
 	FILE *fp;
 	struct sepol_handle *handle;
         unsigned char buffer[BUFSIZ];


This mailing list archive is a service of Copilot Consulting.