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

📄 services.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	context = sidtab_search(&sidtab, sid);	if (!context) {		printk(KERN_ERR "security_sid_to_context:  unrecognized SID "		       "%d\n", sid);		rc = -EINVAL;		goto out_unlock;	}	rc = context_struct_to_string(context, scontext, scontext_len);out_unlock:	POLICY_RDUNLOCK;out:	return rc;}static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid){	char *scontext2;	struct context context;	struct role_datum *role;	struct type_datum *typdatum;	struct user_datum *usrdatum;	char *scontextp, *p, oldc;	int rc = 0;	if (!ss_initialized) {		int i;		for (i = 1; i < SECINITSID_NUM; i++) {			if (!strcmp(initial_sid_to_string[i], scontext)) {				*sid = i;				goto out;			}		}		*sid = SECINITSID_KERNEL;		goto out;	}	*sid = SECSID_NULL;	/* Copy the string so that we can modify the copy as we parse it.	   The string should already by null terminated, but we append a	   null suffix to the copy to avoid problems with the existing	   attr package, which doesn't view the null terminator as part	   of the attribute value. */	scontext2 = kmalloc(scontext_len+1,GFP_KERNEL);	if (!scontext2) {		rc = -ENOMEM;		goto out;	}	memcpy(scontext2, scontext, scontext_len);	scontext2[scontext_len] = 0;	context_init(&context);	*sid = SECSID_NULL;	POLICY_RDLOCK;	/* Parse the security context. */	rc = -EINVAL;	scontextp = (char *) scontext2;	/* Extract the user. */	p = scontextp;	while (*p && *p != ':')		p++;	if (*p == 0)		goto out_unlock;	*p++ = 0;	usrdatum = hashtab_search(policydb.p_users.table, scontextp);	if (!usrdatum)		goto out_unlock;	context.user = usrdatum->value;	/* Extract role. */	scontextp = p;	while (*p && *p != ':')		p++;	if (*p == 0)		goto out_unlock;	*p++ = 0;	role = hashtab_search(policydb.p_roles.table, scontextp);	if (!role)		goto out_unlock;	context.role = role->value;	/* Extract type. */	scontextp = p;	while (*p && *p != ':')		p++;	oldc = *p;	*p++ = 0;	typdatum = hashtab_search(policydb.p_types.table, scontextp);	if (!typdatum)		goto out_unlock;	context.type = typdatum->value;	rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid);	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;}/** * security_context_to_sid - Obtain a SID for a given security context. * @scontext: security context * @scontext_len: length in bytes * @sid: security identifier, SID * * Obtains a SID associated with the security context that * has the string representation specified by @scontext. * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient * memory is available, or 0 on success. */int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid){	return security_context_to_sid_core(scontext, scontext_len,	                                    sid, SECSID_NULL);}/** * security_context_to_sid_default - Obtain a SID for a given security context, * falling back to specified default if needed. * * @scontext: security context * @scontext_len: length in bytes * @sid: security identifier, SID * @def_sid: default SID to assign on errror * * Obtains a SID associated with the security context that * has the string representation specified by @scontext. * The default SID is passed to the MLS layer to be used to allow * kernel labeling of the MLS field if the MLS field is not present * (for upgrading to MLS without full relabel). * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient * memory is available, or 0 on success. */int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid){	return security_context_to_sid_core(scontext, scontext_len,	                                    sid, def_sid);}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, GFP_ATOMIC, AUDIT_SELINUX_ERR,		  "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;	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;	avkey.specified = specified;	avdatum = avtab_search(&policydb.te_avtab, &avkey);	/* If no permanent rule, also check for enabled conditional rules */	if(!avdatum) {		node = avtab_search_node(&policydb.te_cond_avtab, &avkey);		for (; node != NULL; node = avtab_search_node_next(node, specified)) {			if (node->key.specified & AVTAB_ENABLED) {				avdatum = &node->datum;				break;			}		}	}	if (avdatum) {		/* Use the type from the type transition/member/change rule. */		newcontext.type = avdatum->data;	}	/* 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;				}			}		}		break;	default:		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){

⌨️ 快捷键说明

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