diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 0d8b27513bdc..ac7f2b2e3924 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1532,8 +1532,9 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm) | |||
1532 | /* Default to the current task SID. */ | 1532 | /* Default to the current task SID. */ |
1533 | bsec->sid = tsec->sid; | 1533 | bsec->sid = tsec->sid; |
1534 | 1534 | ||
1535 | /* Reset create SID on execve. */ | 1535 | /* Reset create and sockcreate SID on execve. */ |
1536 | tsec->create_sid = 0; | 1536 | tsec->create_sid = 0; |
1537 | tsec->sockcreate_sid = 0; | ||
1537 | 1538 | ||
1538 | if (tsec->exec_sid) { | 1539 | if (tsec->exec_sid) { |
1539 | newsid = tsec->exec_sid; | 1540 | newsid = tsec->exec_sid; |
@@ -2585,9 +2586,10 @@ static int selinux_task_alloc_security(struct task_struct *tsk) | |||
2585 | tsec2->osid = tsec1->osid; | 2586 | tsec2->osid = tsec1->osid; |
2586 | tsec2->sid = tsec1->sid; | 2587 | tsec2->sid = tsec1->sid; |
2587 | 2588 | ||
2588 | /* Retain the exec and create SIDs across fork */ | 2589 | /* Retain the exec, create, and sock SIDs across fork */ |
2589 | tsec2->exec_sid = tsec1->exec_sid; | 2590 | tsec2->exec_sid = tsec1->exec_sid; |
2590 | tsec2->create_sid = tsec1->create_sid; | 2591 | tsec2->create_sid = tsec1->create_sid; |
2592 | tsec2->sockcreate_sid = tsec1->sockcreate_sid; | ||
2591 | 2593 | ||
2592 | /* Retain ptracer SID across fork, if any. | 2594 | /* Retain ptracer SID across fork, if any. |
2593 | This will be reset by the ptrace hook upon any | 2595 | This will be reset by the ptrace hook upon any |
@@ -2937,12 +2939,14 @@ static int selinux_socket_create(int family, int type, | |||
2937 | { | 2939 | { |
2938 | int err = 0; | 2940 | int err = 0; |
2939 | struct task_security_struct *tsec; | 2941 | struct task_security_struct *tsec; |
2942 | u32 newsid; | ||
2940 | 2943 | ||
2941 | if (kern) | 2944 | if (kern) |
2942 | goto out; | 2945 | goto out; |
2943 | 2946 | ||
2944 | tsec = current->security; | 2947 | tsec = current->security; |
2945 | err = avc_has_perm(tsec->sid, tsec->sid, | 2948 | newsid = tsec->sockcreate_sid ? : tsec->sid; |
2949 | err = avc_has_perm(tsec->sid, newsid, | ||
2946 | socket_type_to_security_class(family, type, | 2950 | socket_type_to_security_class(family, type, |
2947 | protocol), SOCKET__CREATE, NULL); | 2951 | protocol), SOCKET__CREATE, NULL); |
2948 | 2952 | ||
@@ -2955,12 +2959,14 @@ static void selinux_socket_post_create(struct socket *sock, int family, | |||
2955 | { | 2959 | { |
2956 | struct inode_security_struct *isec; | 2960 | struct inode_security_struct *isec; |
2957 | struct task_security_struct *tsec; | 2961 | struct task_security_struct *tsec; |
2962 | u32 newsid; | ||
2958 | 2963 | ||
2959 | isec = SOCK_INODE(sock)->i_security; | 2964 | isec = SOCK_INODE(sock)->i_security; |
2960 | 2965 | ||
2961 | tsec = current->security; | 2966 | tsec = current->security; |
2967 | newsid = tsec->sockcreate_sid ? : tsec->sid; | ||
2962 | isec->sclass = socket_type_to_security_class(family, type, protocol); | 2968 | isec->sclass = socket_type_to_security_class(family, type, protocol); |
2963 | isec->sid = kern ? SECINITSID_KERNEL : tsec->sid; | 2969 | isec->sid = kern ? SECINITSID_KERNEL : newsid; |
2964 | isec->initialized = 1; | 2970 | isec->initialized = 1; |
2965 | 2971 | ||
2966 | return; | 2972 | return; |
@@ -4163,6 +4169,8 @@ static int selinux_getprocattr(struct task_struct *p, | |||
4163 | sid = tsec->create_sid; | 4169 | sid = tsec->create_sid; |
4164 | else if (!strcmp(name, "keycreate")) | 4170 | else if (!strcmp(name, "keycreate")) |
4165 | sid = tsec->keycreate_sid; | 4171 | sid = tsec->keycreate_sid; |
4172 | else if (!strcmp(name, "sockcreate")) | ||
4173 | sid = tsec->sockcreate_sid; | ||
4166 | else | 4174 | else |
4167 | return -EINVAL; | 4175 | return -EINVAL; |
4168 | 4176 | ||
@@ -4197,6 +4205,8 @@ static int selinux_setprocattr(struct task_struct *p, | |||
4197 | error = task_has_perm(current, p, PROCESS__SETFSCREATE); | 4205 | error = task_has_perm(current, p, PROCESS__SETFSCREATE); |
4198 | else if (!strcmp(name, "keycreate")) | 4206 | else if (!strcmp(name, "keycreate")) |
4199 | error = task_has_perm(current, p, PROCESS__SETKEYCREATE); | 4207 | error = task_has_perm(current, p, PROCESS__SETKEYCREATE); |
4208 | else if (!strcmp(name, "sockcreate")) | ||
4209 | error = task_has_perm(current, p, PROCESS__SETSOCKCREATE); | ||
4200 | else if (!strcmp(name, "current")) | 4210 | else if (!strcmp(name, "current")) |
4201 | error = task_has_perm(current, p, PROCESS__SETCURRENT); | 4211 | error = task_has_perm(current, p, PROCESS__SETCURRENT); |
4202 | else | 4212 | else |
@@ -4231,7 +4241,9 @@ static int selinux_setprocattr(struct task_struct *p, | |||
4231 | if (error) | 4241 | if (error) |
4232 | return error; | 4242 | return error; |
4233 | tsec->keycreate_sid = sid; | 4243 | tsec->keycreate_sid = sid; |
4234 | } else if (!strcmp(name, "current")) { | 4244 | } else if (!strcmp(name, "sockcreate")) |
4245 | tsec->sockcreate_sid = sid; | ||
4246 | else if (!strcmp(name, "current")) { | ||
4235 | struct av_decision avd; | 4247 | struct av_decision avd; |
4236 | 4248 | ||
4237 | if (sid == 0) | 4249 | if (sid == 0) |