aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2006-06-26 03:26:03 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:26 -0400
commit42c3e03ef6b298813557cdb997bd6db619cd65a2 (patch)
treec2fba776ccf7015d45651ff7d2aee89f06da6f42 /security/selinux/hooks.c
parentc1df7fb88a011b39ea722ac00975c5b8a803261b (diff)
[PATCH] SELinux: Add sockcreate node to procattr API
Below is a patch to add a new /proc/self/attr/sockcreate A process may write a context into this interface and all subsequent sockets created will be labeled with that context. This is the same idea as the fscreate interface where a process can specify the label of a file about to be created. At this time one envisioned user of this will be xinetd. It will be able to better label sockets for the actual services. At this time all sockets take the label of the creating process, so all xinitd sockets would just be labeled the same. I tested this by creating a tcp sender and listener. The sender was able to write to this new proc file and then create sockets with the specified label. I am able to be sure the new label was used since the avc denial messages kicked out by the kernel included both the new security permission setsockcreate and all the socket denials were for the new label, not the label of the running process. Signed-off-by: Eric Paris <eparis@redhat.com> Signed-off-by: James Morris <jmorris@namei.org> Cc: Chris Wright <chrisw@sous-sol.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c22
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)