diff options
Diffstat (limited to 'security/selinux/ss/services.c')
| -rw-r--r-- | security/selinux/ss/services.c | 56 | 
1 files changed, 40 insertions, 16 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 185f849a26f..4321b8fc886 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1018,9 +1018,11 @@ static int context_struct_to_string(struct context *context, char **scontext, u3  	if (context->len) {  		*scontext_len = context->len; -		*scontext = kstrdup(context->str, GFP_ATOMIC); -		if (!(*scontext)) -			return -ENOMEM; +		if (scontext) { +			*scontext = kstrdup(context->str, GFP_ATOMIC); +			if (!(*scontext)) +				return -ENOMEM; +		}  		return 0;  	} @@ -1389,6 +1391,7 @@ static int security_compute_sid(u32 ssid,  				u32 *out_sid,  				bool kern)  { +	struct class_datum *cladatum = NULL;  	struct context *scontext = NULL, *tcontext = NULL, newcontext;  	struct role_trans *roletr = NULL;  	struct avtab_key avkey; @@ -1437,12 +1440,20 @@ static int security_compute_sid(u32 ssid,  		goto out_unlock;  	} +	if (tclass && tclass <= policydb.p_classes.nprim) +		cladatum = policydb.class_val_to_struct[tclass - 1]; +  	/* Set the user identity. */  	switch (specified) {  	case AVTAB_TRANSITION:  	case AVTAB_CHANGE: -		/* Use the process user identity. */ -		newcontext.user = scontext->user; +		if (cladatum && cladatum->default_user == DEFAULT_TARGET) { +			newcontext.user = tcontext->user; +		} else { +			/* notice this gets both DEFAULT_SOURCE and unset */ +			/* Use the process user identity. */ +			newcontext.user = scontext->user; +		}  		break;  	case AVTAB_MEMBER:  		/* Use the related object owner. */ @@ -1450,16 +1461,31 @@ static int security_compute_sid(u32 ssid,  		break;  	} -	/* Set the role and type to default values. */ -	if ((tclass == policydb.process_class) || (sock == true)) { -		/* Use the current role and type of process. */ +	/* Set the role to default values. */ +	if (cladatum && cladatum->default_role == DEFAULT_SOURCE) {  		newcontext.role = scontext->role; -		newcontext.type = scontext->type; +	} else if (cladatum && cladatum->default_role == DEFAULT_TARGET) { +		newcontext.role = tcontext->role;  	} else { -		/* Use the well-defined object role. */ -		newcontext.role = OBJECT_R_VAL; -		/* Use the type of the related object. */ +		if ((tclass == policydb.process_class) || (sock == true)) +			newcontext.role = scontext->role; +		else +			newcontext.role = OBJECT_R_VAL; +	} + +	/* Set the type to default values. */ +	if (cladatum && cladatum->default_type == DEFAULT_SOURCE) { +		newcontext.type = scontext->type; +	} else if (cladatum && cladatum->default_type == DEFAULT_TARGET) {  		newcontext.type = tcontext->type; +	} else { +		if ((tclass == policydb.process_class) || (sock == true)) { +			/* Use the type of process. */ +			newcontext.type = scontext->type; +		} else { +			/* Use the type of the related object. */ +			newcontext.type = tcontext->type; +		}  	}  	/* Look for a type transition/member/change rule. */ @@ -3018,8 +3044,7 @@ out:  static int (*aurule_callback)(void) = audit_update_lsm_rules; -static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, -			       u16 class, u32 perms, u32 *retained) +static int aurule_avc_callback(u32 event)  {  	int err = 0; @@ -3032,8 +3057,7 @@ static int __init aurule_init(void)  {  	int err; -	err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET, -			       SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); +	err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET);  	if (err)  		panic("avc_add_callback() failed, error %d\n", err);  |