示例#1
0
int avtab_read_item(void *fp, struct avtab_datum *avdatum, struct avtab_key *avkey)
{
	__u32 *buf;
	__u32 items, items2;

	memset(avkey, 0, sizeof(struct avtab_key));
	memset(avdatum, 0, sizeof(struct avtab_datum));

	buf = next_entry(fp, sizeof(__u32));
	if (!buf) {
		printk(KERN_ERR "security: avtab: truncated entry\n");
		goto bad;
	}
	items2 = le32_to_cpu(buf[0]);
	buf = next_entry(fp, sizeof(__u32)*items2);
	if (!buf) {
		printk(KERN_ERR "security: avtab: truncated entry\n");
		goto bad;
	}
	items = 0;
	avkey->source_type = le32_to_cpu(buf[items++]);
	avkey->target_type = le32_to_cpu(buf[items++]);
	avkey->target_class = le32_to_cpu(buf[items++]);
	avdatum->specified = le32_to_cpu(buf[items++]);
	if (!(avdatum->specified & (AVTAB_AV | AVTAB_TYPE))) {
		printk(KERN_ERR "security: avtab: null entry\n");
		goto bad;
	}
	if ((avdatum->specified & AVTAB_AV) &&
	    (avdatum->specified & AVTAB_TYPE)) {
		printk(KERN_ERR "security: avtab: entry has both access vectors and types\n");
		goto bad;
	}
	if (avdatum->specified & AVTAB_AV) {
		if (avdatum->specified & AVTAB_ALLOWED)
			avtab_allowed(avdatum) = le32_to_cpu(buf[items++]);
		if (avdatum->specified & AVTAB_AUDITDENY)
			avtab_auditdeny(avdatum) = le32_to_cpu(buf[items++]);
		if (avdatum->specified & AVTAB_AUDITALLOW)
			avtab_auditallow(avdatum) = le32_to_cpu(buf[items++]);
	} else {
		if (avdatum->specified & AVTAB_TRANSITION)
			avtab_transition(avdatum) = le32_to_cpu(buf[items++]);
		if (avdatum->specified & AVTAB_CHANGE)
			avtab_change(avdatum) = le32_to_cpu(buf[items++]);
		if (avdatum->specified & AVTAB_MEMBER)
			avtab_member(avdatum) = le32_to_cpu(buf[items++]);
	}
	if (items != items2) {
		printk(KERN_ERR "security: avtab: entry only had %d items, expected %d\n",
		       items2, items);
		goto bad;
	}

	return 0;
bad:
	return -1;
}
示例#2
0
static int security_compute_sid(u32 ssid,
				u32 tsid,
				u16 tclass,
				u32 specified,
				u32 *out_sid)
{
	struct context *scontext = 0, *tcontext = 0, newcontext;
	struct role_trans *roletr = 0;
	struct avtab_key avkey;
	struct avtab_datum *avdatum;
	unsigned int type_change = 0;
	int rc = 0;

	if (!ss_initialized) {
		switch (tclass) {
		case SECCLASS_PROCESS:
			*out_sid = ssid;
			break;
		default:
			*out_sid = tsid;
			break;
		}
		goto out;
	}

	POLICY_RDLOCK;

	scontext = sidtab_search(&sidtab, ssid);
	if (!scontext) {
		printk(KERN_ERR "security_compute_sid:  unrecognized SID %d\n",
		       ssid);
		rc = -EINVAL;
		goto out_unlock;
	}
	tcontext = sidtab_search(&sidtab, tsid);
	if (!tcontext) {
		printk(KERN_ERR "security_compute_sid:  unrecognized SID %d\n",
		       tsid);
		rc = -EINVAL;
		goto out_unlock;
	}

	context_init(&newcontext);

	/* Set the user identity. */
	switch (specified) {
	case AVTAB_TRANSITION:
	case AVTAB_CHANGE:
		/* Use the process user identity. */
		newcontext.user = scontext->user;
		break;
	case AVTAB_MEMBER:
		/* Use the related object owner. */
		newcontext.user = tcontext->user;
		break;
	}

	/* Set the role and type to default values. */
	switch (tclass) {
	case SECCLASS_PROCESS:
		/* Use the current role and type of process. */
		newcontext.role = scontext->role;
		newcontext.type = scontext->type;
		break;
	default:
		/* Use the well-defined object role. */
		newcontext.role = OBJECT_R_VAL;
		/* Use the type of the related object. */
		newcontext.type = tcontext->type;
	}

	/* Look for a type transition/member/change rule. */
	avkey.source_type = scontext->type;
	avkey.target_type = tcontext->type;
	avkey.target_class = tclass;
	avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_TYPE);
	type_change = (avdatum && (avdatum->specified & specified));
	if (type_change) {
		/* Use the type from the type transition/member/change rule. */
		switch (specified) {
		case AVTAB_TRANSITION:
			newcontext.type = avtab_transition(avdatum);
			break;
		case AVTAB_MEMBER:
			newcontext.type = avtab_member(avdatum);
			break;
		case AVTAB_CHANGE:
			newcontext.type = avtab_change(avdatum);
			break;
		}
	}

	/* Check for class-specific changes. */
	switch (tclass) {
	case SECCLASS_PROCESS:
		if (specified & AVTAB_TRANSITION) {
			/* Look for a role transition rule. */
			for (roletr = policydb.role_tr; roletr;
			     roletr = roletr->next) {
				if (roletr->role == scontext->role &&
				    roletr->type == tcontext->type) {
					/* Use the role transition rule. */
					newcontext.role = roletr->new_role;
					break;
				}
			}
		}

		if (!type_change && !roletr) {
			/* No change in process role or type. */
			*out_sid = ssid;
			goto out_unlock;

		}
		break;
	default:
		if (!type_change &&
		    (newcontext.user == tcontext->user) &&
		    mls_context_cmp(scontext, tcontext)) {
                        /* No change in object type, owner,
			   or MLS attributes. */
			*out_sid = tsid;
			goto out_unlock;
		}
		break;
	}

	/* Set the MLS attributes.
	   This is done last because it may allocate memory. */
	rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext);
	if (rc)
		goto out_unlock;

	/* Check the validity of the context. */
	if (!policydb_context_isvalid(&policydb, &newcontext)) {
		rc = compute_sid_handle_invalid_context(scontext,
							tcontext,
							tclass,
							&newcontext);
		if (rc)
			goto out_unlock;
	}
	/* Obtain the sid for the context. */
	rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid);
out_unlock:
	POLICY_RDUNLOCK;
	context_destroy(&newcontext);
out:
	return rc;
}