diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 13384fef0d60..0d8b27513bdc 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1099,6 +1099,17 @@ static int may_create(struct inode *dir, | |||
1099 | FILESYSTEM__ASSOCIATE, &ad); | 1099 | FILESYSTEM__ASSOCIATE, &ad); |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | /* Check whether a task can create a key. */ | ||
1103 | static int may_create_key(u32 ksid, | ||
1104 | struct task_struct *ctx) | ||
1105 | { | ||
1106 | struct task_security_struct *tsec; | ||
1107 | |||
1108 | tsec = ctx->security; | ||
1109 | |||
1110 | return avc_has_perm(tsec->sid, ksid, SECCLASS_KEY, KEY__CREATE, NULL); | ||
1111 | } | ||
1112 | |||
1102 | #define MAY_LINK 0 | 1113 | #define MAY_LINK 0 |
1103 | #define MAY_UNLINK 1 | 1114 | #define MAY_UNLINK 1 |
1104 | #define MAY_RMDIR 2 | 1115 | #define MAY_RMDIR 2 |
@@ -4150,6 +4161,8 @@ static int selinux_getprocattr(struct task_struct *p, | |||
4150 | sid = tsec->exec_sid; | 4161 | sid = tsec->exec_sid; |
4151 | else if (!strcmp(name, "fscreate")) | 4162 | else if (!strcmp(name, "fscreate")) |
4152 | sid = tsec->create_sid; | 4163 | sid = tsec->create_sid; |
4164 | else if (!strcmp(name, "keycreate")) | ||
4165 | sid = tsec->keycreate_sid; | ||
4153 | else | 4166 | else |
4154 | return -EINVAL; | 4167 | return -EINVAL; |
4155 | 4168 | ||
@@ -4182,6 +4195,8 @@ static int selinux_setprocattr(struct task_struct *p, | |||
4182 | error = task_has_perm(current, p, PROCESS__SETEXEC); | 4195 | error = task_has_perm(current, p, PROCESS__SETEXEC); |
4183 | else if (!strcmp(name, "fscreate")) | 4196 | else if (!strcmp(name, "fscreate")) |
4184 | error = task_has_perm(current, p, PROCESS__SETFSCREATE); | 4197 | error = task_has_perm(current, p, PROCESS__SETFSCREATE); |
4198 | else if (!strcmp(name, "keycreate")) | ||
4199 | error = task_has_perm(current, p, PROCESS__SETKEYCREATE); | ||
4185 | else if (!strcmp(name, "current")) | 4200 | else if (!strcmp(name, "current")) |
4186 | error = task_has_perm(current, p, PROCESS__SETCURRENT); | 4201 | error = task_has_perm(current, p, PROCESS__SETCURRENT); |
4187 | else | 4202 | else |
@@ -4211,7 +4226,12 @@ static int selinux_setprocattr(struct task_struct *p, | |||
4211 | tsec->exec_sid = sid; | 4226 | tsec->exec_sid = sid; |
4212 | else if (!strcmp(name, "fscreate")) | 4227 | else if (!strcmp(name, "fscreate")) |
4213 | tsec->create_sid = sid; | 4228 | tsec->create_sid = sid; |
4214 | else if (!strcmp(name, "current")) { | 4229 | else if (!strcmp(name, "keycreate")) { |
4230 | error = may_create_key(sid, p); | ||
4231 | if (error) | ||
4232 | return error; | ||
4233 | tsec->keycreate_sid = sid; | ||
4234 | } else if (!strcmp(name, "current")) { | ||
4215 | struct av_decision avd; | 4235 | struct av_decision avd; |
4216 | 4236 | ||
4217 | if (sid == 0) | 4237 | if (sid == 0) |
@@ -4275,7 +4295,10 @@ static int selinux_key_alloc(struct key *k, struct task_struct *tsk, | |||
4275 | return -ENOMEM; | 4295 | return -ENOMEM; |
4276 | 4296 | ||
4277 | ksec->obj = k; | 4297 | ksec->obj = k; |
4278 | ksec->sid = tsec->sid; | 4298 | if (tsec->keycreate_sid) |
4299 | ksec->sid = tsec->keycreate_sid; | ||
4300 | else | ||
4301 | ksec->sid = tsec->sid; | ||
4279 | k->security = ksec; | 4302 | k->security = ksec; |
4280 | 4303 | ||
4281 | return 0; | 4304 | return 0; |
@@ -4514,10 +4537,10 @@ static __init int selinux_init(void) | |||
4514 | 4537 | ||
4515 | #ifdef CONFIG_KEYS | 4538 | #ifdef CONFIG_KEYS |
4516 | /* Add security information to initial keyrings */ | 4539 | /* Add security information to initial keyrings */ |
4517 | security_key_alloc(&root_user_keyring, current, | 4540 | selinux_key_alloc(&root_user_keyring, current, |
4518 | KEY_ALLOC_NOT_IN_QUOTA); | 4541 | KEY_ALLOC_NOT_IN_QUOTA); |
4519 | security_key_alloc(&root_session_keyring, current, | 4542 | selinux_key_alloc(&root_session_keyring, current, |
4520 | KEY_ALLOC_NOT_IN_QUOTA); | 4543 | KEY_ALLOC_NOT_IN_QUOTA); |
4521 | #endif | 4544 | #endif |
4522 | 4545 | ||
4523 | return 0; | 4546 | return 0; |