diff options
Diffstat (limited to 'security/selinux')
| -rw-r--r-- | security/selinux/hooks.c | 56 | ||||
| -rw-r--r-- | security/selinux/include/av_perm_to_string.h | 3 | ||||
| -rw-r--r-- | security/selinux/include/av_permissions.h | 4 | ||||
| -rw-r--r-- | security/selinux/include/objsec.h | 2 |
4 files changed, 56 insertions, 9 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 79c16e31c884..28832e689800 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,10 @@ 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 fs, key, and sock SIDs on execve. */ |
| 1525 | tsec->create_sid = 0; | 1536 | tsec->create_sid = 0; |
| 1537 | tsec->keycreate_sid = 0; | ||
| 1538 | tsec->sockcreate_sid = 0; | ||
| 1526 | 1539 | ||
| 1527 | if (tsec->exec_sid) { | 1540 | if (tsec->exec_sid) { |
| 1528 | newsid = tsec->exec_sid; | 1541 | newsid = tsec->exec_sid; |
| @@ -2574,9 +2587,11 @@ static int selinux_task_alloc_security(struct task_struct *tsk) | |||
| 2574 | tsec2->osid = tsec1->osid; | 2587 | tsec2->osid = tsec1->osid; |
| 2575 | tsec2->sid = tsec1->sid; | 2588 | tsec2->sid = tsec1->sid; |
| 2576 | 2589 | ||
| 2577 | /* Retain the exec and create SIDs across fork */ | 2590 | /* Retain the exec, fs, key, and sock SIDs across fork */ |
| 2578 | tsec2->exec_sid = tsec1->exec_sid; | 2591 | tsec2->exec_sid = tsec1->exec_sid; |
| 2579 | tsec2->create_sid = tsec1->create_sid; | 2592 | tsec2->create_sid = tsec1->create_sid; |
| 2593 | tsec2->keycreate_sid = tsec1->keycreate_sid; | ||
| 2594 | tsec2->sockcreate_sid = tsec1->sockcreate_sid; | ||
| 2580 | 2595 | ||
| 2581 | /* Retain ptracer SID across fork, if any. | 2596 | /* Retain ptracer SID across fork, if any. |
| 2582 | This will be reset by the ptrace hook upon any | 2597 | This will be reset by the ptrace hook upon any |
| @@ -2926,12 +2941,14 @@ static int selinux_socket_create(int family, int type, | |||
| 2926 | { | 2941 | { |
| 2927 | int err = 0; | 2942 | int err = 0; |
| 2928 | struct task_security_struct *tsec; | 2943 | struct task_security_struct *tsec; |
| 2944 | u32 newsid; | ||
| 2929 | 2945 | ||
| 2930 | if (kern) | 2946 | if (kern) |
| 2931 | goto out; | 2947 | goto out; |
| 2932 | 2948 | ||
| 2933 | tsec = current->security; | 2949 | tsec = current->security; |
| 2934 | err = avc_has_perm(tsec->sid, tsec->sid, | 2950 | newsid = tsec->sockcreate_sid ? : tsec->sid; |
| 2951 | err = avc_has_perm(tsec->sid, newsid, | ||
| 2935 | socket_type_to_security_class(family, type, | 2952 | socket_type_to_security_class(family, type, |
| 2936 | protocol), SOCKET__CREATE, NULL); | 2953 | protocol), SOCKET__CREATE, NULL); |
| 2937 | 2954 | ||
| @@ -2944,12 +2961,14 @@ static void selinux_socket_post_create(struct socket *sock, int family, | |||
| 2944 | { | 2961 | { |
| 2945 | struct inode_security_struct *isec; | 2962 | struct inode_security_struct *isec; |
| 2946 | struct task_security_struct *tsec; | 2963 | struct task_security_struct *tsec; |
| 2964 | u32 newsid; | ||
| 2947 | 2965 | ||
| 2948 | isec = SOCK_INODE(sock)->i_security; | 2966 | isec = SOCK_INODE(sock)->i_security; |
| 2949 | 2967 | ||
| 2950 | tsec = current->security; | 2968 | tsec = current->security; |
| 2969 | newsid = tsec->sockcreate_sid ? : tsec->sid; | ||
| 2951 | isec->sclass = socket_type_to_security_class(family, type, protocol); | 2970 | isec->sclass = socket_type_to_security_class(family, type, protocol); |
| 2952 | isec->sid = kern ? SECINITSID_KERNEL : tsec->sid; | 2971 | isec->sid = kern ? SECINITSID_KERNEL : newsid; |
| 2953 | isec->initialized = 1; | 2972 | isec->initialized = 1; |
| 2954 | 2973 | ||
| 2955 | return; | 2974 | return; |
| @@ -4150,6 +4169,10 @@ static int selinux_getprocattr(struct task_struct *p, | |||
| 4150 | sid = tsec->exec_sid; | 4169 | sid = tsec->exec_sid; |
| 4151 | else if (!strcmp(name, "fscreate")) | 4170 | else if (!strcmp(name, "fscreate")) |
| 4152 | sid = tsec->create_sid; | 4171 | sid = tsec->create_sid; |
| 4172 | else if (!strcmp(name, "keycreate")) | ||
| 4173 | sid = tsec->keycreate_sid; | ||
| 4174 | else if (!strcmp(name, "sockcreate")) | ||
| 4175 | sid = tsec->sockcreate_sid; | ||
| 4153 | else | 4176 | else |
| 4154 | return -EINVAL; | 4177 | return -EINVAL; |
| 4155 | 4178 | ||
| @@ -4182,6 +4205,10 @@ static int selinux_setprocattr(struct task_struct *p, | |||
| 4182 | error = task_has_perm(current, p, PROCESS__SETEXEC); | 4205 | error = task_has_perm(current, p, PROCESS__SETEXEC); |
| 4183 | else if (!strcmp(name, "fscreate")) | 4206 | else if (!strcmp(name, "fscreate")) |
| 4184 | error = task_has_perm(current, p, PROCESS__SETFSCREATE); | 4207 | error = task_has_perm(current, p, PROCESS__SETFSCREATE); |
| 4208 | else if (!strcmp(name, "keycreate")) | ||
| 4209 | error = task_has_perm(current, p, PROCESS__SETKEYCREATE); | ||
| 4210 | else if (!strcmp(name, "sockcreate")) | ||
| 4211 | error = task_has_perm(current, p, PROCESS__SETSOCKCREATE); | ||
| 4185 | else if (!strcmp(name, "current")) | 4212 | else if (!strcmp(name, "current")) |
| 4186 | error = task_has_perm(current, p, PROCESS__SETCURRENT); | 4213 | error = task_has_perm(current, p, PROCESS__SETCURRENT); |
| 4187 | else | 4214 | else |
| @@ -4211,6 +4238,13 @@ static int selinux_setprocattr(struct task_struct *p, | |||
| 4211 | tsec->exec_sid = sid; | 4238 | tsec->exec_sid = sid; |
| 4212 | else if (!strcmp(name, "fscreate")) | 4239 | else if (!strcmp(name, "fscreate")) |
| 4213 | tsec->create_sid = sid; | 4240 | tsec->create_sid = sid; |
| 4241 | else if (!strcmp(name, "keycreate")) { | ||
| 4242 | error = may_create_key(sid, p); | ||
| 4243 | if (error) | ||
| 4244 | return error; | ||
| 4245 | tsec->keycreate_sid = sid; | ||
| 4246 | } else if (!strcmp(name, "sockcreate")) | ||
| 4247 | tsec->sockcreate_sid = sid; | ||
| 4214 | else if (!strcmp(name, "current")) { | 4248 | else if (!strcmp(name, "current")) { |
| 4215 | struct av_decision avd; | 4249 | struct av_decision avd; |
| 4216 | 4250 | ||
| @@ -4264,7 +4298,8 @@ static int selinux_setprocattr(struct task_struct *p, | |||
| 4264 | 4298 | ||
| 4265 | #ifdef CONFIG_KEYS | 4299 | #ifdef CONFIG_KEYS |
| 4266 | 4300 | ||
| 4267 | static int selinux_key_alloc(struct key *k, struct task_struct *tsk) | 4301 | static int selinux_key_alloc(struct key *k, struct task_struct *tsk, |
| 4302 | unsigned long flags) | ||
| 4268 | { | 4303 | { |
| 4269 | struct task_security_struct *tsec = tsk->security; | 4304 | struct task_security_struct *tsec = tsk->security; |
| 4270 | struct key_security_struct *ksec; | 4305 | struct key_security_struct *ksec; |
| @@ -4274,7 +4309,10 @@ static int selinux_key_alloc(struct key *k, struct task_struct *tsk) | |||
| 4274 | return -ENOMEM; | 4309 | return -ENOMEM; |
| 4275 | 4310 | ||
| 4276 | ksec->obj = k; | 4311 | ksec->obj = k; |
| 4277 | ksec->sid = tsec->sid; | 4312 | if (tsec->keycreate_sid) |
| 4313 | ksec->sid = tsec->keycreate_sid; | ||
| 4314 | else | ||
| 4315 | ksec->sid = tsec->sid; | ||
| 4278 | k->security = ksec; | 4316 | k->security = ksec; |
| 4279 | 4317 | ||
| 4280 | return 0; | 4318 | return 0; |
| @@ -4513,8 +4551,10 @@ static __init int selinux_init(void) | |||
| 4513 | 4551 | ||
| 4514 | #ifdef CONFIG_KEYS | 4552 | #ifdef CONFIG_KEYS |
| 4515 | /* Add security information to initial keyrings */ | 4553 | /* Add security information to initial keyrings */ |
| 4516 | security_key_alloc(&root_user_keyring, current); | 4554 | selinux_key_alloc(&root_user_keyring, current, |
| 4517 | security_key_alloc(&root_session_keyring, current); | 4555 | KEY_ALLOC_NOT_IN_QUOTA); |
| 4556 | selinux_key_alloc(&root_session_keyring, current, | ||
| 4557 | KEY_ALLOC_NOT_IN_QUOTA); | ||
| 4518 | #endif | 4558 | #endif |
| 4519 | 4559 | ||
| 4520 | return 0; | 4560 | return 0; |
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index bc020bde6c86..7c9b58380833 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h | |||
| @@ -72,6 +72,8 @@ | |||
| 72 | S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem") | 72 | S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem") |
| 73 | S_(SECCLASS_PROCESS, PROCESS__EXECSTACK, "execstack") | 73 | S_(SECCLASS_PROCESS, PROCESS__EXECSTACK, "execstack") |
| 74 | S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap") | 74 | S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap") |
| 75 | S_(SECCLASS_PROCESS, PROCESS__SETKEYCREATE, "setkeycreate") | ||
| 76 | S_(SECCLASS_PROCESS, PROCESS__SETSOCKCREATE, "setsockcreate") | ||
| 75 | S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue") | 77 | S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue") |
| 76 | S_(SECCLASS_MSG, MSG__SEND, "send") | 78 | S_(SECCLASS_MSG, MSG__SEND, "send") |
| 77 | S_(SECCLASS_MSG, MSG__RECEIVE, "receive") | 79 | S_(SECCLASS_MSG, MSG__RECEIVE, "receive") |
| @@ -248,3 +250,4 @@ | |||
| 248 | S_(SECCLASS_KEY, KEY__SEARCH, "search") | 250 | S_(SECCLASS_KEY, KEY__SEARCH, "search") |
| 249 | S_(SECCLASS_KEY, KEY__LINK, "link") | 251 | S_(SECCLASS_KEY, KEY__LINK, "link") |
| 250 | S_(SECCLASS_KEY, KEY__SETATTR, "setattr") | 252 | S_(SECCLASS_KEY, KEY__SETATTR, "setattr") |
| 253 | S_(SECCLASS_KEY, KEY__CREATE, "create") | ||
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index 1205227a3a33..69fd4b48202c 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h | |||
| @@ -467,6 +467,8 @@ | |||
| 467 | #define PROCESS__EXECMEM 0x02000000UL | 467 | #define PROCESS__EXECMEM 0x02000000UL |
| 468 | #define PROCESS__EXECSTACK 0x04000000UL | 468 | #define PROCESS__EXECSTACK 0x04000000UL |
| 469 | #define PROCESS__EXECHEAP 0x08000000UL | 469 | #define PROCESS__EXECHEAP 0x08000000UL |
| 470 | #define PROCESS__SETKEYCREATE 0x10000000UL | ||
| 471 | #define PROCESS__SETSOCKCREATE 0x20000000UL | ||
| 470 | 472 | ||
| 471 | #define IPC__CREATE 0x00000001UL | 473 | #define IPC__CREATE 0x00000001UL |
| 472 | #define IPC__DESTROY 0x00000002UL | 474 | #define IPC__DESTROY 0x00000002UL |
| @@ -966,4 +968,4 @@ | |||
| 966 | #define KEY__SEARCH 0x00000008UL | 968 | #define KEY__SEARCH 0x00000008UL |
| 967 | #define KEY__LINK 0x00000010UL | 969 | #define KEY__LINK 0x00000010UL |
| 968 | #define KEY__SETATTR 0x00000020UL | 970 | #define KEY__SETATTR 0x00000020UL |
| 969 | 971 | #define KEY__CREATE 0x00000040UL | |
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 8f5547ad1856..cf54a304169a 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
| @@ -32,6 +32,8 @@ struct task_security_struct { | |||
| 32 | u32 sid; /* current SID */ | 32 | u32 sid; /* current SID */ |
| 33 | u32 exec_sid; /* exec SID */ | 33 | u32 exec_sid; /* exec SID */ |
| 34 | u32 create_sid; /* fscreate SID */ | 34 | u32 create_sid; /* fscreate SID */ |
| 35 | u32 keycreate_sid; /* keycreate SID */ | ||
| 36 | u32 sockcreate_sid; /* fscreate SID */ | ||
| 35 | u32 ptrace_sid; /* SID of ptrace parent */ | 37 | u32 ptrace_sid; /* SID of ptrace parent */ |
| 36 | }; | 38 | }; |
| 37 | 39 | ||
