Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ee0c823 authored by Eric Paris's avatar Eric Paris Committed by James Morris
Browse files

SELinux: seperate range transition rules to a seperate function



Move the range transition rule to a separate function, range_read(), rather
than doing it all in policydb_read()

Signed-off-by: default avatarEric Paris <eparis@redhat.com>
Acked-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent d2f8b234
Loading
Loading
Loading
Loading
+75 −64
Original line number Diff line number Diff line
@@ -1701,6 +1701,78 @@ u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name)
	return 1U << (perdatum->value-1);
}

static int range_read(struct policydb *p, void *fp)
{
	struct range_trans *rt = NULL;
	struct mls_range *r = NULL;
	int i, rc;
	__le32 buf[2];
	u32 nel;

	if (p->policyvers < POLICYDB_VERSION_MLS)
		return 0;

	rc = next_entry(buf, fp, sizeof(u32));
	if (rc)
		goto out;

	nel = le32_to_cpu(buf[0]);
	for (i = 0; i < nel; i++) {
		rc = -ENOMEM;
		rt = kzalloc(sizeof(*rt), GFP_KERNEL);
		if (!rt)
			goto out;

		rc = next_entry(buf, fp, (sizeof(u32) * 2));
		if (rc)
			goto out;

		rt->source_type = le32_to_cpu(buf[0]);
		rt->target_type = le32_to_cpu(buf[1]);
		if (p->policyvers >= POLICYDB_VERSION_RANGETRANS) {
			rc = next_entry(buf, fp, sizeof(u32));
			if (rc)
				goto out;
			rt->target_class = le32_to_cpu(buf[0]);
		} else
			rt->target_class = p->process_class;

		rc = -EINVAL;
		if (!policydb_type_isvalid(p, rt->source_type) ||
		    !policydb_type_isvalid(p, rt->target_type) ||
		    !policydb_class_isvalid(p, rt->target_class))
			goto out;

		rc = -ENOMEM;
		r = kzalloc(sizeof(*r), GFP_KERNEL);
		if (!r)
			goto out;

		rc = mls_read_range_helper(r, fp);
		if (rc)
			goto out;

		rc = -EINVAL;
		if (!mls_range_isvalid(p, r)) {
			printk(KERN_WARNING "SELinux:  rangetrans:  invalid range\n");
			goto out;
		}

		rc = hashtab_insert(p->range_tr, rt, r);
		if (rc)
			goto out;

		rt = NULL;
		r = NULL;
	}
	rangetr_hash_eval(p->range_tr);
	rc = 0;
out:
	kfree(rt);
	kfree(r);
	return rc;
}

/*
 * Read the configuration data from a policy database binary
 * representation file into a policy database structure.
@@ -1717,8 +1789,6 @@ int policydb_read(struct policydb *p, void *fp)
	u32 len, len2, nprim, nel, nel2;
	char *policydb_str;
	struct policydb_compat_info *info;
	struct range_trans *rt;
	struct mls_range *r;

	rc = policydb_init(p);
	if (rc)
@@ -2131,68 +2201,9 @@ int policydb_read(struct policydb *p, void *fp)
		}
	}

	if (p->policyvers >= POLICYDB_VERSION_MLS) {
		int new_rangetr = p->policyvers >= POLICYDB_VERSION_RANGETRANS;
		rc = next_entry(buf, fp, sizeof(u32));
		if (rc < 0)
			goto bad;
		nel = le32_to_cpu(buf[0]);
		for (i = 0; i < nel; i++) {
			rt = kzalloc(sizeof(*rt), GFP_KERNEL);
			if (!rt) {
				rc = -ENOMEM;
				goto bad;
			}
			rc = next_entry(buf, fp, (sizeof(u32) * 2));
			if (rc < 0) {
				kfree(rt);
				goto bad;
			}
			rt->source_type = le32_to_cpu(buf[0]);
			rt->target_type = le32_to_cpu(buf[1]);
			if (new_rangetr) {
				rc = next_entry(buf, fp, sizeof(u32));
				if (rc < 0) {
					kfree(rt);
					goto bad;
				}
				rt->target_class = le32_to_cpu(buf[0]);
			} else
				rt->target_class = p->process_class;
			if (!policydb_type_isvalid(p, rt->source_type) ||
			    !policydb_type_isvalid(p, rt->target_type) ||
			    !policydb_class_isvalid(p, rt->target_class)) {
				kfree(rt);
				rc = -EINVAL;
				goto bad;
			}
			r = kzalloc(sizeof(*r), GFP_KERNEL);
			if (!r) {
				kfree(rt);
				rc = -ENOMEM;
				goto bad;
			}
			rc = mls_read_range_helper(r, fp);
			if (rc) {
				kfree(rt);
				kfree(r);
				goto bad;
			}
			if (!mls_range_isvalid(p, r)) {
				printk(KERN_WARNING "SELinux:  rangetrans:  invalid range\n");
				kfree(rt);
				kfree(r);
				goto bad;
			}
			rc = hashtab_insert(p->range_tr, rt, r);
			if (rc) {
				kfree(rt);
				kfree(r);
	rc = range_read(p, fp);
	if (rc)
		goto bad;
			}
		}
		rangetr_hash_eval(p->range_tr);
	}

	p->type_attr_map = kmalloc(p->p_types.nprim * sizeof(struct ebitmap), GFP_KERNEL);
	if (!p->type_attr_map)