diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 79c16e31c884..ac7f2b2e3924 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 |
@@ -1521,8 +1532,9 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm) | |||
1521 | /* Default to the current task SID. */ | 1532 | /* Default to the current task SID. */ |
1522 | bsec->sid = tsec->sid; | 1533 | bsec->sid = tsec->sid; |
1523 | 1534 | ||
1524 | /* Reset create SID on execve. */ | 1535 | /* Reset create and sockcreate SID on execve. */ |
1525 | tsec->create_sid = 0; | 1536 | tsec->create_sid = 0; |
1537 | tsec->sockcreate_sid = 0; | ||
1526 | 1538 | ||
1527 | if (tsec->exec_sid) { | 1539 | if (tsec->exec_sid) { |
1528 | newsid = tsec->exec_sid; | 1540 | newsid = tsec->exec_sid; |
@@ -2574,9 +2586,10 @@ static int selinux_task_alloc_security(struct task_struct *tsk) | |||
2574 | tsec2->osid = tsec1->osid; | 2586 | tsec2->osid = tsec1->osid; |
2575 | tsec2->sid = tsec1->sid; | 2587 | tsec2->sid = tsec1->sid; |
2576 | 2588 | ||
2577 | /* Retain the exec and create SIDs across fork */ | 2589 | /* Retain the exec, create, and sock SIDs across fork */ |
2578 | tsec2->exec_sid = tsec1->exec_sid; | 2590 | tsec2->exec_sid = tsec1->exec_sid; |
2579 | tsec2->create_sid = tsec1->create_sid; | 2591 | tsec2->create_sid = tsec1->create_sid; |
2592 | tsec2->sockcreate_sid = tsec1->sockcreate_sid; | ||
2580 | 2593 | ||
2581 | /* Retain ptracer SID across fork, if any. | 2594 | /* Retain ptracer SID across fork, if any. |
2582 | This will be reset by the ptrace hook upon any | 2595 | This will be reset by the ptrace hook upon any |
@@ -2926,12 +2939,14 @@ static int selinux_socket_create(int family, int type, | |||
2926 | { | 2939 | { |
2927 | int err = 0; | 2940 | int err = 0; |
2928 | struct task_security_struct *tsec; | 2941 | struct task_security_struct *tsec; |
2942 | u32 newsid; | ||
2929 | 2943 | ||
2930 | if (kern) | 2944 | if (kern) |
2931 | goto out; | 2945 | goto out; |
2932 | 2946 | ||
2933 | tsec = current->security; | 2947 | tsec = current->security; |
2934 | err = avc_has_perm(tsec->sid, tsec->sid, | 2948 | newsid = tsec->sockcreate_sid ? : tsec->sid; |
2949 | err = avc_has_perm(tsec->sid, newsid, | ||
2935 | socket_type_to_security_class(family, type, | 2950 | socket_type_to_security_class(family, type, |
2936 | protocol), SOCKET__CREATE, NULL); | 2951 | protocol), SOCKET__CREATE, NULL); |
2937 | 2952 | ||
@@ -2944,12 +2959,14 @@ static void selinux_socket_post_create(struct socket *sock, int family, | |||
2944 | { | 2959 | { |
2945 | struct inode_security_struct *isec; | 2960 | struct inode_security_struct *isec; |
2946 | struct task_security_struct *tsec; | 2961 | struct task_security_struct *tsec; |
2962 | u32 newsid; | ||
2947 | 2963 | ||
2948 | isec = SOCK_INODE(sock)->i_security; | 2964 | isec = SOCK_INODE(sock)->i_security; |
2949 | 2965 | ||
2950 | tsec = current->security; | 2966 | tsec = current->security; |
2967 | newsid = tsec->sockcreate_sid ? : tsec->sid; | ||
2951 | isec->sclass = socket_type_to_security_class(family, type, protocol); | 2968 | isec->sclass = socket_type_to_security_class(family, type, protocol); |
2952 | isec->sid = kern ? SECINITSID_KERNEL : tsec->sid; | 2969 | isec->sid = kern ? SECINITSID_KERNEL : newsid; |
2953 | isec->initialized = 1; | 2970 | isec->initialized = 1; |
2954 | 2971 | ||
2955 | return; | 2972 | return; |
@@ -4150,6 +4167,10 @@ static int selinux_getprocattr(struct task_struct *p, | |||
4150 | sid = tsec->exec_sid; | 4167 | sid = tsec->exec_sid; |
4151 | else if (!strcmp(name, "fscreate")) | 4168 | else if (!strcmp(name, "fscreate")) |
4152 | sid = tsec->create_sid; | 4169 | sid = tsec->create_sid; |
4170 | else if (!strcmp(name, "keycreate")) | ||
4171 | sid = tsec->keycreate_sid; | ||
4172 | else if (!strcmp(name, "sockcreate")) | ||
4173 | sid = tsec->sockcreate_sid; | ||
4153 | else | 4174 | else |
4154 | return -EINVAL; | 4175 | return -EINVAL; |
4155 | 4176 | ||
@@ -4182,6 +4203,10 @@ static int selinux_setprocattr(struct task_struct *p, | |||
4182 | error = task_has_perm(current, p, PROCESS__SETEXEC); | 4203 | error = task_has_perm(current, p, PROCESS__SETEXEC); |
4183 | else if (!strcmp(name, "fscreate")) | 4204 | else if (!strcmp(name, "fscreate")) |
4184 | error = task_has_perm(current, p, PROCESS__SETFSCREATE); | 4205 | error = task_has_perm(current, p, PROCESS__SETFSCREATE); |
4206 | else if (!strcmp(name, "keycreate")) | ||
4207 | error = task_has_perm(current, p, PROCESS__SETKEYCREATE); | ||
4208 | else if (!strcmp(name, "sockcreate")) | ||
4209 | error = task_has_perm(current, p, PROCESS__SETSOCKCREATE); | ||
4185 | else if (!strcmp(name, "current")) | 4210 | else if (!strcmp(name, "current")) |
4186 | error = task_has_perm(current, p, PROCESS__SETCURRENT); | 4211 | error = task_has_perm(current, p, PROCESS__SETCURRENT); |
4187 | else | 4212 | else |
@@ -4211,6 +4236,13 @@ static int selinux_setprocattr(struct task_struct *p, | |||
4211 | tsec->exec_sid = sid; | 4236 | tsec->exec_sid = sid; |
4212 | else if (!strcmp(name, "fscreate")) | 4237 | else if (!strcmp(name, "fscreate")) |
4213 | tsec->create_sid = sid; | 4238 | tsec->create_sid = sid; |
4239 | else if (!strcmp(name, "keycreate")) { | ||
4240 | error = may_create_key(sid, p); | ||
4241 | if (error) | ||
4242 | return error; | ||
4243 | tsec->keycreate_sid = sid; | ||
4244 | } else if (!strcmp(name, "sockcreate")) | ||
4245 | tsec->sockcreate_sid = sid; | ||
4214 | else if (!strcmp(name, "current")) { | 4246 | else if (!strcmp(name, "current")) { |
4215 | struct av_decision avd; | 4247 | struct av_decision avd; |
4216 | 4248 | ||
@@ -4264,7 +4296,8 @@ static int selinux_setprocattr(struct task_struct *p, | |||
4264 | 4296 | ||
4265 | #ifdef CONFIG_KEYS | 4297 | #ifdef CONFIG_KEYS |
4266 | 4298 | ||
4267 | static int selinux_key_alloc(struct key *k, struct task_struct *tsk) | 4299 | static int selinux_key_alloc(struct key *k, struct task_struct *tsk, |
4300 | unsigned long flags) | ||
4268 | { | 4301 | { |
4269 | struct task_security_struct *tsec = tsk->security; | 4302 | struct task_security_struct *tsec = tsk->security; |
4270 | struct key_security_struct *ksec; | 4303 | struct key_security_struct *ksec; |
@@ -4274,7 +4307,10 @@ static int selinux_key_alloc(struct key *k, struct task_struct *tsk) | |||
4274 | return -ENOMEM; | 4307 | return -ENOMEM; |
4275 | 4308 | ||
4276 | ksec->obj = k; | 4309 | ksec->obj = k; |
4277 | ksec->sid = tsec->sid; | 4310 | if (tsec->keycreate_sid) |
4311 | ksec->sid = tsec->keycreate_sid; | ||
4312 | else | ||
4313 | ksec->sid = tsec->sid; | ||
4278 | k->security = ksec; | 4314 | k->security = ksec; |
4279 | 4315 | ||
4280 | return 0; | 4316 | return 0; |
@@ -4513,8 +4549,10 @@ static __init int selinux_init(void) | |||
4513 | 4549 | ||
4514 | #ifdef CONFIG_KEYS | 4550 | #ifdef CONFIG_KEYS |
4515 | /* Add security information to initial keyrings */ | 4551 | /* Add security information to initial keyrings */ |
4516 | security_key_alloc(&root_user_keyring, current); | 4552 | selinux_key_alloc(&root_user_keyring, current, |
4517 | security_key_alloc(&root_session_keyring, current); | 4553 | KEY_ALLOC_NOT_IN_QUOTA); |
4554 | selinux_key_alloc(&root_session_keyring, current, | ||
4555 | KEY_ALLOC_NOT_IN_QUOTA); | ||
4518 | #endif | 4556 | #endif |
4519 | 4557 | ||
4520 | return 0; | 4558 | return 0; |