⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 services.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	rc = mls_context_to_sid(oldc, &p, &context);	if (rc)		goto out_unlock;	if ((p - scontext2) < scontext_len) {		rc = -EINVAL;		goto out_unlock;	}	/* Check the validity of the new context. */	if (!policydb_context_isvalid(&policydb, &context)) {		rc = -EINVAL;		goto out_unlock;	}	/* Obtain the new sid. */	rc = sidtab_context_to_sid(&sidtab, &context, sid);out_unlock:	POLICY_RDUNLOCK;	context_destroy(&context);	kfree(scontext2);out:	return rc;}static int compute_sid_handle_invalid_context(	struct context *scontext,	struct context *tcontext,	u16 tclass,	struct context *newcontext){	char *s = NULL, *t = NULL, *n = NULL;	u32 slen, tlen, nlen;	if (context_struct_to_string(scontext, &s, &slen) < 0)		goto out;	if (context_struct_to_string(tcontext, &t, &tlen) < 0)		goto out;	if (context_struct_to_string(newcontext, &n, &nlen) < 0)		goto out;	audit_log(current->audit_context,		  "security_compute_sid:  invalid context %s"		  " for scontext=%s"		  " tcontext=%s"		  " tclass=%s",		  n, s, t, policydb.p_class_val_to_name[tclass-1]);out:	kfree(s);	kfree(t);	kfree(n);	if (!selinux_enforcing)		return 0;	return -EACCES;}static int security_compute_sid(u32 ssid,				u32 tsid,				u16 tclass,				u32 specified,				u32 *out_sid){	struct context *scontext = NULL, *tcontext = NULL, newcontext;	struct role_trans *roletr = NULL;	struct avtab_key avkey;	struct avtab_datum *avdatum;	struct avtab_node *node;	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);	/* If no permanent rule, also check for enabled conditional rules */	if(!avdatum) {		node = avtab_search_node(&policydb.te_cond_avtab, &avkey, specified);		for (; node != NULL; node = avtab_search_node_next(node, specified)) {			if (node->datum.specified & AVTAB_ENABLED) {				avdatum = &node->datum;				break;			}		}	}	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;}/** * security_transition_sid - Compute the SID for a new subject/object. * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class * @out_sid: security identifier for new subject/object * * Compute a SID to use for labeling a new subject or object in the * class @tclass based on a SID pair (@ssid, @tsid). * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM * if insufficient memory is available, or %0 if the new SID was * computed successfully. */int security_transition_sid(u32 ssid,			    u32 tsid,			    u16 tclass,			    u32 *out_sid){	return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid);}/** * security_member_sid - Compute the SID for member selection. * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class * @out_sid: security identifier for selected member * * Compute a SID to use when selecting a member of a polyinstantiated * object of class @tclass based on a SID pair (@ssid, @tsid). * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM * if insufficient memory is available, or %0 if the SID was * computed successfully. */int security_member_sid(u32 ssid,			u32 tsid,			u16 tclass,			u32 *out_sid){	return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid);}/** * security_change_sid - Compute the SID for object relabeling. * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class * @out_sid: security identifier for selected member * * Compute a SID to use for relabeling an object of class @tclass * based on a SID pair (@ssid, @tsid). * Return -%EINVAL if any of the parameters are invalid, -%ENOMEM * if insufficient memory is available, or %0 if the SID was * computed successfully. */int security_change_sid(u32 ssid,			u32 tsid,			u16 tclass,			u32 *out_sid){	return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid);}/* * Verify that each permission that is defined under the * existing policy is still defined with the same value * in the new policy. */static int validate_perm(void *key, void *datum, void *p){	struct hashtab *h;	struct perm_datum *perdatum, *perdatum2;	int rc = 0;	h = p;	perdatum = datum;	perdatum2 = hashtab_search(h, key);	if (!perdatum2) {		printk(KERN_ERR "security:  permission %s disappeared",		       (char *)key);		rc = -ENOENT;		goto out;	}	if (perdatum->value != perdatum2->value) {		printk(KERN_ERR "security:  the value of permission %s changed",		       (char *)key);		rc = -EINVAL;	}out:	return rc;}/* * 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;}/* Clone the SID into the new SID table. */static int clone_sid(u32 sid,		     struct context *context,		     void *arg){	struct sidtab *s = arg;	return sidtab_insert(s, sid, context);}static inline int convert_context_handle_invalid_context(struct context *context){	int rc = 0;	if (selinux_enforcing) {		rc = -EINVAL;	} else {		char *s;		u32 len;		context_struct_to_string(context, &s, &len);		printk(KERN_ERR "security:  context %s is invalid\n", s);		kfree(s);	}	return rc;}struct convert_context_args {	struct policydb *oldp;	struct policydb *newp;};/* * Convert the values in the security context * structure `c' from the values specified * in the policy `p->oldp' to the values specified * in the policy `p->newp'.  Verify that the * context is valid under the new policy. */static int convert_context(u32 key,			   struct context *c,			   void *p){	struct convert_context_args *args;	struct context oldc;	struct role_datum *role;	struct type_datum *typdatum;	struct user_datum *usrdatum;	char *s;	u32 len;	int rc;	args = p;	rc = context_cpy(&oldc, c);	if (rc)		goto out;	rc = -EINVAL;	/* Convert the user. */	usrdatum = hashtab_search(args->newp->p_users.table,	                          args->oldp->p_user_val_to_name[c->user - 1]);	if (!usrdatum) {		goto bad;	}	c->user = usrdatum->value;	/* Convert the role. */	role = hashtab_search(args->newp->p_roles.table,	                      args->oldp->p_role_val_to_name[c->role - 1]);	if (!role) {		goto bad;	}	c->role = role->value;	/* Convert the type. */	typdatum = hashtab_search(args->newp->p_types.table,	                          args->oldp->p_type_val_to_name[c->type - 1]);	if (!typdatum) {		goto bad;	}	c->type = typdatum->value;	rc = mls_convert_context(args->oldp, args->newp, c);	if (rc)		goto bad;	/* Check the validity of the new context. */	if (!policydb_context_isvalid(args->newp, c)) {		rc = convert_context_handle_invalid_context(&oldc);		if (rc)			goto bad;	}	context_destroy(&oldc);out:	return rc;bad:	context_struct_to_string(&oldc, &s, &len);	context_destroy(&oldc);	printk(KERN_ERR "security:  invalidating context %s\n", s);	kfree(s);	goto out;}extern void selinux_complete_init(void);/** * 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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -