diff options
author | Eric Paris <eparis@redhat.com> | 2006-06-26 03:26:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 12:58:26 -0400 |
commit | 42c3e03ef6b298813557cdb997bd6db619cd65a2 (patch) | |
tree | c2fba776ccf7015d45651ff7d2aee89f06da6f42 | |
parent | c1df7fb88a011b39ea722ac00975c5b8a803261b (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.c | 6 | ||||
-rw-r--r-- | security/selinux/hooks.c | 22 | ||||
-rw-r--r-- | security/selinux/include/av_perm_to_string.h | 1 | ||||
-rw-r--r-- | security/selinux/include/av_permissions.h | 1 | ||||
-rw-r--r-- | security/selinux/include/objsec.h | 1 |
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 | }; |
296 | static struct pid_entry tid_attr_stuff[] = { | 299 | static 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 | ||