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

Commit 98d74e08 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/selinux-2.6:
  SELinux: add more validity checks on policy load
  SELinux: fix bug in new ebitmap code.
  SELinux: suppress a warning for 64k pages.
parents e4fc5a1a 45e5421e
Loading
Loading
Loading
Loading
+28 −4
Original line number Diff line number Diff line
@@ -325,7 +325,7 @@ static uint16_t spec_order[] = {
	AVTAB_MEMBER
};

int avtab_read_item(void *fp, u32 vers, struct avtab *a,
int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
	            int (*insertf)(struct avtab *a, struct avtab_key *k,
				   struct avtab_datum *d, void *p),
		    void *p)
@@ -333,10 +333,11 @@ int avtab_read_item(void *fp, u32 vers, struct avtab *a,
	__le16 buf16[4];
	u16 enabled;
	__le32 buf32[7];
	u32 items, items2, val;
	u32 items, items2, val, vers = pol->policyvers;
	struct avtab_key key;
	struct avtab_datum datum;
	int i, rc;
	unsigned set;

	memset(&key, 0, sizeof(struct avtab_key));
	memset(&datum, 0, sizeof(struct avtab_datum));
@@ -420,12 +421,35 @@ int avtab_read_item(void *fp, u32 vers, struct avtab *a,
	key.target_class = le16_to_cpu(buf16[items++]);
	key.specified = le16_to_cpu(buf16[items++]);

	if (!policydb_type_isvalid(pol, key.source_type) ||
	    !policydb_type_isvalid(pol, key.target_type) ||
	    !policydb_class_isvalid(pol, key.target_class)) {
		printk(KERN_WARNING "security: avtab: invalid type or class\n");
		return -1;
	}

	set = 0;
	for (i = 0; i < ARRAY_SIZE(spec_order); i++) {
		if (key.specified & spec_order[i])
			set++;
	}
	if (!set || set > 1) {
		printk(KERN_WARNING
			"security:  avtab:  more than one specifier\n");
		return -1;
	}

	rc = next_entry(buf32, fp, sizeof(u32));
	if (rc < 0) {
		printk("security: avtab: truncated entry\n");
		return -1;
	}
	datum.data = le32_to_cpu(*buf32);
	if ((key.specified & AVTAB_TYPE) &&
	    !policydb_type_isvalid(pol, datum.data)) {
		printk(KERN_WARNING "security: avtab: invalid type\n");
		return -1;
	}
	return insertf(a, &key, &datum, p);
}

@@ -435,7 +459,7 @@ static int avtab_insertf(struct avtab *a, struct avtab_key *k,
	return avtab_insert(a, k, d);
}

int avtab_read(struct avtab *a, void *fp, u32 vers)
int avtab_read(struct avtab *a, void *fp, struct policydb *pol)
{
	int rc;
	__le32 buf[1];
@@ -459,7 +483,7 @@ int avtab_read(struct avtab *a, void *fp, u32 vers)
		goto bad;

	for (i = 0; i < nel; i++) {
		rc = avtab_read_item(fp,vers, a, avtab_insertf, NULL);
		rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL);
		if (rc) {
			if (rc == -ENOMEM)
				printk(KERN_ERR "security: avtab: out of memory\n");
+3 −2
Original line number Diff line number Diff line
@@ -64,12 +64,13 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k);
void avtab_destroy(struct avtab *h);
void avtab_hash_eval(struct avtab *h, char *tag);

int avtab_read_item(void *fp, uint32_t vers, struct avtab *a,
struct policydb;
int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
		    int (*insert)(struct avtab *a, struct avtab_key *k,
				  struct avtab_datum *d, void *p),
		    void *p);

int avtab_read(struct avtab *a, void *fp, u32 vers);
int avtab_read(struct avtab *a, void *fp, struct policydb *pol);

struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key,
					  struct avtab_datum *datum);
+2 −1
Original line number Diff line number Diff line
@@ -362,7 +362,8 @@ static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list *
	data.head = NULL;
	data.tail = NULL;
	for (i = 0; i < len; i++) {
		rc = avtab_read_item(fp, p->policyvers, &p->te_cond_avtab, cond_insertf, &data);
		rc = avtab_read_item(&p->te_cond_avtab, fp, p, cond_insertf,
				     &data);
		if (rc)
			return rc;

+1 −1
Original line number Diff line number Diff line
@@ -129,8 +129,8 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
			cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
			c_iter->bitmap[cmap_idx]
				|= e_iter->maps[cmap_idx] << cmap_sft;
			e_iter = e_iter->next;
		}
		e_iter = e_iter->next;
	}

	return 0;
+36 −30
Original line number Diff line number Diff line
@@ -157,49 +157,55 @@ void mls_sid_to_context(struct context *context,
	return;
}

/*
 * Return 1 if the MLS fields in the security context
 * structure `c' are valid.  Return 0 otherwise.
 */
int mls_context_isvalid(struct policydb *p, struct context *c)
int mls_level_isvalid(struct policydb *p, struct mls_level *l)
{
	struct level_datum *levdatum;
	struct user_datum *usrdatum;
	struct ebitmap_node *node;
	int i, l;

	if (!selinux_mls_enabled)
		return 1;
	int i;

	/*
	 * MLS range validity checks: high must dominate low, low level must
	 * be valid (category set <-> sensitivity check), and high level must
	 * be valid (category set <-> sensitivity check)
	 */
	if (!mls_level_dom(&c->range.level[1], &c->range.level[0]))
		/* High does not dominate low. */
		return 0;

	for (l = 0; l < 2; l++) {
		if (!c->range.level[l].sens || c->range.level[l].sens > p->p_levels.nprim)
	if (!l->sens || l->sens > p->p_levels.nprim)
		return 0;
	levdatum = hashtab_search(p->p_levels.table,
			p->p_sens_val_to_name[c->range.level[l].sens - 1]);
				  p->p_sens_val_to_name[l->sens - 1]);
	if (!levdatum)
		return 0;

		ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) {
	ebitmap_for_each_positive_bit(&l->cat, node, i) {
		if (i > p->p_cats.nprim)
			return 0;
			if (!ebitmap_get_bit(&levdatum->level->cat, i))
		if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
			/*
			 * Category may not be associated with
				 * sensitivity in low level.
			 * sensitivity.
			 */
			return 0;
		}
	}

	return 1;
}

int mls_range_isvalid(struct policydb *p, struct mls_range *r)
{
	return (mls_level_isvalid(p, &r->level[0]) &&
		mls_level_isvalid(p, &r->level[1]) &&
		mls_level_dom(&r->level[1], &r->level[0]));
}

/*
 * Return 1 if the MLS fields in the security context
 * structure `c' are valid.  Return 0 otherwise.
 */
int mls_context_isvalid(struct policydb *p, struct context *c)
{
	struct user_datum *usrdatum;

	if (!selinux_mls_enabled)
		return 1;

	if (!mls_range_isvalid(p, &c->range))
		return 0;

	if (c->role == OBJECT_R_VAL)
		return 1;

Loading