aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--fs/proc/base.c6
-rw-r--r--security/selinux/hooks.c22
-rw-r--r--security/selinux/include/av_perm_to_string.h1
-rw-r--r--security/selinux/include/av_permissions.h1
-rw-r--r--security/selinux/include/objsec.h1
5 files changed, 26 insertions, 5 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 43871c85729d..6ba7785319de 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -132,6 +132,7 @@ enum pid_directory_inos {
132 PROC_TGID_ATTR_EXEC, 132 PROC_TGID_ATTR_EXEC,
133 PROC_TGID_ATTR_FSCREATE, 133 PROC_TGID_ATTR_FSCREATE,
134 PROC_TGID_ATTR_KEYCREATE, 134 PROC_TGID_ATTR_KEYCREATE,
135 PROC_TGID_ATTR_SOCKCREATE,
135#endif 136#endif
136#ifdef CONFIG_AUDITSYSCALL 137#ifdef CONFIG_AUDITSYSCALL
137 PROC_TGID_LOGINUID, 138 PROC_TGID_LOGINUID,
@@ -174,6 +175,7 @@ enum pid_directory_inos {
174 PROC_TID_ATTR_EXEC, 175 PROC_TID_ATTR_EXEC,
175 PROC_TID_ATTR_FSCREATE, 176 PROC_TID_ATTR_FSCREATE,
176 PROC_TID_ATTR_KEYCREATE, 177 PROC_TID_ATTR_KEYCREATE,
178 PROC_TID_ATTR_SOCKCREATE,
177#endif 179#endif
178#ifdef CONFIG_AUDITSYSCALL 180#ifdef CONFIG_AUDITSYSCALL
179 PROC_TID_LOGINUID, 181 PROC_TID_LOGINUID,
@@ -291,6 +293,7 @@ static struct pid_entry tgid_attr_stuff[] = {
291 E(PROC_TGID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO), 293 E(PROC_TGID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
292 E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO), 294 E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
293 E(PROC_TGID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO), 295 E(PROC_TGID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
296 E(PROC_TGID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
294 {0,0,NULL,0} 297 {0,0,NULL,0}
295}; 298};
296static struct pid_entry tid_attr_stuff[] = { 299static struct pid_entry tid_attr_stuff[] = {
@@ -299,6 +302,7 @@ static struct pid_entry tid_attr_stuff[] = {
299 E(PROC_TID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO), 302 E(PROC_TID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
300 E(PROC_TID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO), 303 E(PROC_TID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
301 E(PROC_TID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO), 304 E(PROC_TID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
305 E(PROC_TID_ATTR_SOCKCREATE, "sockcreate", S_IFREG|S_IRUGO|S_IWUGO),
302 {0,0,NULL,0} 306 {0,0,NULL,0}
303}; 307};
304#endif 308#endif
@@ -1764,6 +1768,8 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
1764 case PROC_TGID_ATTR_FSCREATE: 1768 case PROC_TGID_ATTR_FSCREATE:
1765 case PROC_TID_ATTR_KEYCREATE: 1769 case PROC_TID_ATTR_KEYCREATE:
1766 case PROC_TGID_ATTR_KEYCREATE: 1770 case PROC_TGID_ATTR_KEYCREATE:
1771 case PROC_TID_ATTR_SOCKCREATE:
1772 case PROC_TGID_ATTR_SOCKCREATE:
1767 inode->i_fop = &proc_pid_attr_operations; 1773 inode->i_fop = &proc_pid_attr_operations;
1768 break; 1774 break;
1769#endif 1775#endif
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)
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index e777578ccd9d..7c9b58380833 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -73,6 +73,7 @@
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") 75 S_(SECCLASS_PROCESS, PROCESS__SETKEYCREATE, "setkeycreate")
76 S_(SECCLASS_PROCESS, PROCESS__SETSOCKCREATE, "setsockcreate")
76 S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue") 77 S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue")
77 S_(SECCLASS_MSG, MSG__SEND, "send") 78 S_(SECCLASS_MSG, MSG__SEND, "send")
78 S_(SECCLASS_MSG, MSG__RECEIVE, "receive") 79 S_(SECCLASS_MSG, MSG__RECEIVE, "receive")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index 1e1678023b68..69fd4b48202c 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -468,6 +468,7 @@
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 470#define PROCESS__SETKEYCREATE 0x10000000UL
471#define PROCESS__SETSOCKCREATE 0x20000000UL
471 472
472#define IPC__CREATE 0x00000001UL 473#define IPC__CREATE 0x00000001UL
473#define IPC__DESTROY 0x00000002UL 474#define IPC__DESTROY 0x00000002UL
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 191b3e4484ce..cf54a304169a 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -33,6 +33,7 @@ struct task_security_struct {
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 */ 35 u32 keycreate_sid; /* keycreate SID */
36 u32 sockcreate_sid; /* fscreate SID */
36 u32 ptrace_sid; /* SID of ptrace parent */ 37 u32 ptrace_sid; /* SID of ptrace parent */
37}; 38};
38 39