diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 54adc9d31e92..524915dfda64 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -4252,6 +4252,57 @@ static int selinux_setprocattr(struct task_struct *p, | |||
4252 | return size; | 4252 | return size; |
4253 | } | 4253 | } |
4254 | 4254 | ||
4255 | #ifdef CONFIG_KEYS | ||
4256 | |||
4257 | static int selinux_key_alloc(struct key *k, struct task_struct *tsk) | ||
4258 | { | ||
4259 | struct task_security_struct *tsec = tsk->security; | ||
4260 | struct key_security_struct *ksec; | ||
4261 | |||
4262 | ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL); | ||
4263 | if (!ksec) | ||
4264 | return -ENOMEM; | ||
4265 | |||
4266 | ksec->obj = k; | ||
4267 | ksec->sid = tsec->sid; | ||
4268 | k->security = ksec; | ||
4269 | |||
4270 | return 0; | ||
4271 | } | ||
4272 | |||
4273 | static void selinux_key_free(struct key *k) | ||
4274 | { | ||
4275 | struct key_security_struct *ksec = k->security; | ||
4276 | |||
4277 | k->security = NULL; | ||
4278 | kfree(ksec); | ||
4279 | } | ||
4280 | |||
4281 | static int selinux_key_permission(key_ref_t key_ref, | ||
4282 | struct task_struct *ctx, | ||
4283 | key_perm_t perm) | ||
4284 | { | ||
4285 | struct key *key; | ||
4286 | struct task_security_struct *tsec; | ||
4287 | struct key_security_struct *ksec; | ||
4288 | |||
4289 | key = key_ref_to_ptr(key_ref); | ||
4290 | |||
4291 | tsec = ctx->security; | ||
4292 | ksec = key->security; | ||
4293 | |||
4294 | /* if no specific permissions are requested, we skip the | ||
4295 | permission check. No serious, additional covert channels | ||
4296 | appear to be created. */ | ||
4297 | if (perm == 0) | ||
4298 | return 0; | ||
4299 | |||
4300 | return avc_has_perm(tsec->sid, ksec->sid, | ||
4301 | SECCLASS_KEY, perm, NULL); | ||
4302 | } | ||
4303 | |||
4304 | #endif | ||
4305 | |||
4255 | static struct security_operations selinux_ops = { | 4306 | static struct security_operations selinux_ops = { |
4256 | .ptrace = selinux_ptrace, | 4307 | .ptrace = selinux_ptrace, |
4257 | .capget = selinux_capget, | 4308 | .capget = selinux_capget, |
@@ -4406,6 +4457,12 @@ static struct security_operations selinux_ops = { | |||
4406 | .xfrm_state_delete_security = selinux_xfrm_state_delete, | 4457 | .xfrm_state_delete_security = selinux_xfrm_state_delete, |
4407 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, | 4458 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, |
4408 | #endif | 4459 | #endif |
4460 | |||
4461 | #ifdef CONFIG_KEYS | ||
4462 | .key_alloc = selinux_key_alloc, | ||
4463 | .key_free = selinux_key_free, | ||
4464 | .key_permission = selinux_key_permission, | ||
4465 | #endif | ||
4409 | }; | 4466 | }; |
4410 | 4467 | ||
4411 | static __init int selinux_init(void) | 4468 | static __init int selinux_init(void) |
@@ -4441,6 +4498,13 @@ static __init int selinux_init(void) | |||
4441 | } else { | 4498 | } else { |
4442 | printk(KERN_INFO "SELinux: Starting in permissive mode\n"); | 4499 | printk(KERN_INFO "SELinux: Starting in permissive mode\n"); |
4443 | } | 4500 | } |
4501 | |||
4502 | #ifdef CONFIG_KEYS | ||
4503 | /* Add security information to initial keyrings */ | ||
4504 | security_key_alloc(&root_user_keyring, current); | ||
4505 | security_key_alloc(&root_session_keyring, current); | ||
4506 | #endif | ||
4507 | |||
4444 | return 0; | 4508 | return 0; |
4445 | } | 4509 | } |
4446 | 4510 | ||