Beispiel #1
0
/*
 * Verify that each class that is defined under the
 * existing policy is still defined with the same
 * attributes in the new policy.
 */
static int validate_class(void *key, void *datum, void *p)
{
	struct policydb *newp;
	struct class_datum *cladatum, *cladatum2;
	int rc;

	newp = p;
	cladatum = datum;

	cladatum2 = hashtab_search(newp->p_classes.table, key);
	if (!cladatum2) {
		printk(KERN_ERR "security:  class %s disappeared\n",
		       (char *)key);
		rc = -ENOENT;
		goto out;
	}
	if (cladatum->value != cladatum2->value) {
		printk(KERN_ERR "security:  the value of class %s changed\n",
		       (char *)key);
		rc = -EINVAL;
		goto out;
	}
	if ((cladatum->comdatum && !cladatum2->comdatum) ||
	    (!cladatum->comdatum && cladatum2->comdatum)) {
		printk(KERN_ERR "security:  the inherits clause for the access "
		       "vector definition for class %s changed\n", (char *)key);
		rc = -EINVAL;
		goto out;
	}
	if (cladatum->comdatum) {
		rc = hashtab_map(cladatum->comdatum->permissions.table, validate_perm,
		                 cladatum2->comdatum->permissions.table);
		if (rc) {
			printk(" in the access vector definition for class "
			       "%s\n", (char *)key);
			goto out;
		}
	}
	rc = hashtab_map(cladatum->permissions.table, validate_perm,
	                 cladatum2->permissions.table);
	if (rc)
		printk(" in access vector definition for class %s\n",
		       (char *)key);
out:
	return rc;
}
Beispiel #2
0
char *sepol_av_to_string(policydb_t * policydbp, uint32_t tclass,
			 sepol_access_vector_t av)
{
	struct val_to_name v;
	static char avbuf[1024];
	class_datum_t *cladatum;
	char *perm = NULL, *p;
	unsigned int i;
	int rc;
	int avlen = 0, len;

	cladatum = policydbp->class_val_to_struct[tclass - 1];
	p = avbuf;
	for (i = 0; i < cladatum->permissions.nprim; i++) {
		if (av & (1 << i)) {
			v.val = i + 1;
			rc = hashtab_map(cladatum->permissions.table,
					 perm_name, &v);
			if (!rc && cladatum->comdatum) {
				rc = hashtab_map(cladatum->comdatum->
						 permissions.table, perm_name,
						 &v);
			}
			if (rc)
				perm = v.name;
			if (perm) {
				len =
				    snprintf(p, sizeof(avbuf) - avlen, " %s",
					     perm);
				if (len < 0
				    || (size_t) len >= (sizeof(avbuf) - avlen))
					return NULL;
				p += len;
				avlen += len;
			}
		}
	}

	return avbuf;
}
Beispiel #3
0
/**
 * security_load_policy - Load a security policy configuration.
 * @data: binary policy data
 * @len: length of data in bytes
 *
 * Load a new set of security policy configuration data,
 * validate it and convert the SID table as necessary.
 * This function will flush the access vector cache after
 * loading the new policy.
 */
int security_load_policy(void *data, size_t len)
{
	struct policydb oldpolicydb, newpolicydb;
	struct sidtab oldsidtab, newsidtab;
	struct convert_context_args args;
	u32 seqno;
	int rc = 0;
	struct policy_file file = { data, len }, *fp = &file;

	LOAD_LOCK;

	if (!ss_initialized) {
		if (policydb_read(&policydb, fp)) {
			LOAD_UNLOCK;
			return -EINVAL;
		}
		if (policydb_load_isids(&policydb, &sidtab)) {
			LOAD_UNLOCK;
			policydb_destroy(&policydb);
			return -EINVAL;
		}
		ss_initialized = 1;
		LOAD_UNLOCK;
		selinux_complete_init();
		return 0;
	}

#if 0
	sidtab_hash_eval(&sidtab, "sids");
#endif

	if (policydb_read(&newpolicydb, fp)) {
		LOAD_UNLOCK;
		return -EINVAL;
	}

	sidtab_init(&newsidtab);

	/* Verify that the existing classes did not change. */
	if (hashtab_map(policydb.p_classes.table, validate_class, &newpolicydb)) {
		printk(KERN_ERR "security:  the definition of an existing "
		       "class changed\n");
		rc = -EINVAL;
		goto err;
	}

	/* Clone the SID table. */
	sidtab_shutdown(&sidtab);
	if (sidtab_map(&sidtab, clone_sid, &newsidtab)) {
		rc = -ENOMEM;
		goto err;
	}

	/* Convert the internal representations of contexts
	   in the new SID table and remove invalid SIDs. */
	args.oldp = &policydb;
	args.newp = &newpolicydb;
	sidtab_map_remove_on_error(&newsidtab, convert_context, &args);

	/* Save the old policydb and SID table to free later. */
	memcpy(&oldpolicydb, &policydb, sizeof policydb);
	sidtab_set(&oldsidtab, &sidtab);

	/* Install the new policydb and SID table. */
	POLICY_WRLOCK;
	memcpy(&policydb, &newpolicydb, sizeof policydb);
	sidtab_set(&sidtab, &newsidtab);
	seqno = ++latest_granting;
	POLICY_WRUNLOCK;
	LOAD_UNLOCK;

	/* Free the old policydb and SID table. */
	policydb_destroy(&oldpolicydb);
	sidtab_destroy(&oldsidtab);

	avc_ss_reset(seqno);

	return 0;

err:
	LOAD_UNLOCK;
	sidtab_destroy(&newsidtab);
	policydb_destroy(&newpolicydb);
	return rc;

}