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 185f849a26f6..4321b8fc8863 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); |