aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael LeMay <mdlemay@epoch.ncsc.mil>2006-06-26 03:24:57 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:18 -0400
commit4eb582cf1fbd7b9e5f466e3718a59c957e75254e (patch)
tree4387e460a50efa8d46a54526d0cf0959c0e3b428
parent06ec7be557a1259611d6093a00463c42650dc71a (diff)
[PATCH] keys: add a way to store the appropriate context for newly-created keys
Add a /proc/<pid>/attr/keycreate entry that stores the appropriate context for newly-created keys. Modify the selinux_key_alloc hook to make use of the new entry. Update the flask headers to include a new "setkeycreate" permission for processes. Update the flask headers to include a new "create" permission for keys. Use the create permission to restrict which SIDs each task can assign to newly-created keys. Add a new parameter to the security hook "security_key_alloc" to indicate whether it is being invoked by the kernel, or from userspace. If it is being invoked by the kernel, the security hook should never fail. Update the documentation to reflect these changes. Signed-off-by: Michael LeMay <mdlemay@epoch.ncsc.mil> Signed-off-by: James Morris <jmorris@namei.org> Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--Documentation/keys.txt27
-rw-r--r--fs/proc/base.c6
-rw-r--r--security/selinux/hooks.c35
-rw-r--r--security/selinux/include/av_perm_to_string.h2
-rw-r--r--security/selinux/include/av_permissions.h3
-rw-r--r--security/selinux/include/objsec.h1
6 files changed, 56 insertions, 18 deletions
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index 70e83cf664ae..61c0fad2fe2f 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -241,25 +241,30 @@ The security class "key" has been added to SELinux so that mandatory access
241controls can be applied to keys created within various contexts. This support 241controls can be applied to keys created within various contexts. This support
242is preliminary, and is likely to change quite significantly in the near future. 242is preliminary, and is likely to change quite significantly in the near future.
243Currently, all of the basic permissions explained above are provided in SELinux 243Currently, all of the basic permissions explained above are provided in SELinux
244as well; SE Linux is simply invoked after all basic permission checks have been 244as well; SELinux is simply invoked after all basic permission checks have been
245performed. 245performed.
246 246
247Each key is labeled with the same context as the task to which it belongs. 247The value of the file /proc/self/attr/keycreate influences the labeling of
248Typically, this is the same task that was running when the key was created. 248newly-created keys. If the contents of that file correspond to an SELinux
249The default keyrings are handled differently, but in a way that is very 249security context, then the key will be assigned that context. Otherwise, the
250intuitive: 250key will be assigned the current context of the task that invoked the key
251creation request. Tasks must be granted explicit permission to assign a
252particular context to newly-created keys, using the "create" permission in the
253key security class.
251 254
252 (*) The user and user session keyrings that are created when the user logs in 255The default keyrings associated with users will be labeled with the default
253 are currently labeled with the context of the login manager. 256context of the user if and only if the login programs have been instrumented to
254 257properly initialize keycreate during the login process. Otherwise, they will
255 (*) The keyrings associated with new threads are each labeled with the context 258be labeled with the context of the login program itself.
256 of their associated thread, and both session and process keyrings are
257 handled similarly.
258 259
259Note, however, that the default keyrings associated with the root user are 260Note, however, that the default keyrings associated with the root user are
260labeled with the default kernel context, since they are created early in the 261labeled with the default kernel context, since they are created early in the
261boot process, before root has a chance to log in. 262boot process, before root has a chance to log in.
262 263
264The keyrings associated with new threads are each labeled with the context of
265their associated thread, and both session and process keyrings are handled
266similarly.
267
263 268
264================ 269================
265NEW PROCFS FILES 270NEW PROCFS FILES
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 6afff725a8c9..c4a1ff371b8d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -121,6 +121,7 @@ enum pid_directory_inos {
121 PROC_TGID_ATTR_PREV, 121 PROC_TGID_ATTR_PREV,
122 PROC_TGID_ATTR_EXEC, 122 PROC_TGID_ATTR_EXEC,
123 PROC_TGID_ATTR_FSCREATE, 123 PROC_TGID_ATTR_FSCREATE,
124 PROC_TGID_ATTR_KEYCREATE,
124#endif 125#endif
125#ifdef CONFIG_AUDITSYSCALL 126#ifdef CONFIG_AUDITSYSCALL
126 PROC_TGID_LOGINUID, 127 PROC_TGID_LOGINUID,
@@ -162,6 +163,7 @@ enum pid_directory_inos {
162 PROC_TID_ATTR_PREV, 163 PROC_TID_ATTR_PREV,
163 PROC_TID_ATTR_EXEC, 164 PROC_TID_ATTR_EXEC,
164 PROC_TID_ATTR_FSCREATE, 165 PROC_TID_ATTR_FSCREATE,
166 PROC_TID_ATTR_KEYCREATE,
165#endif 167#endif
166#ifdef CONFIG_AUDITSYSCALL 168#ifdef CONFIG_AUDITSYSCALL
167 PROC_TID_LOGINUID, 169 PROC_TID_LOGINUID,
@@ -275,6 +277,7 @@ static struct pid_entry tgid_attr_stuff[] = {
275 E(PROC_TGID_ATTR_PREV, "prev", S_IFREG|S_IRUGO), 277 E(PROC_TGID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
276 E(PROC_TGID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO), 278 E(PROC_TGID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
277 E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO), 279 E(PROC_TGID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
280 E(PROC_TGID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
278 {0,0,NULL,0} 281 {0,0,NULL,0}
279}; 282};
280static struct pid_entry tid_attr_stuff[] = { 283static struct pid_entry tid_attr_stuff[] = {
@@ -282,6 +285,7 @@ static struct pid_entry tid_attr_stuff[] = {
282 E(PROC_TID_ATTR_PREV, "prev", S_IFREG|S_IRUGO), 285 E(PROC_TID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
283 E(PROC_TID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO), 286 E(PROC_TID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
284 E(PROC_TID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO), 287 E(PROC_TID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
288 E(PROC_TID_ATTR_KEYCREATE, "keycreate", S_IFREG|S_IRUGO|S_IWUGO),
285 {0,0,NULL,0} 289 {0,0,NULL,0}
286}; 290};
287#endif 291#endif
@@ -1801,6 +1805,8 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
1801 case PROC_TGID_ATTR_EXEC: 1805 case PROC_TGID_ATTR_EXEC:
1802 case PROC_TID_ATTR_FSCREATE: 1806 case PROC_TID_ATTR_FSCREATE:
1803 case PROC_TGID_ATTR_FSCREATE: 1807 case PROC_TGID_ATTR_FSCREATE:
1808 case PROC_TID_ATTR_KEYCREATE:
1809 case PROC_TGID_ATTR_KEYCREATE:
1804 inode->i_fop = &proc_pid_attr_operations; 1810 inode->i_fop = &proc_pid_attr_operations;
1805 break; 1811 break;
1806#endif 1812#endif
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 13384fef0d60..0d8b27513bdc 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. */
1103static 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
@@ -4150,6 +4161,8 @@ static int selinux_getprocattr(struct task_struct *p,
4150 sid = tsec->exec_sid; 4161 sid = tsec->exec_sid;
4151 else if (!strcmp(name, "fscreate")) 4162 else if (!strcmp(name, "fscreate"))
4152 sid = tsec->create_sid; 4163 sid = tsec->create_sid;
4164 else if (!strcmp(name, "keycreate"))
4165 sid = tsec->keycreate_sid;
4153 else 4166 else
4154 return -EINVAL; 4167 return -EINVAL;
4155 4168
@@ -4182,6 +4195,8 @@ static int selinux_setprocattr(struct task_struct *p,
4182 error = task_has_perm(current, p, PROCESS__SETEXEC); 4195 error = task_has_perm(current, p, PROCESS__SETEXEC);
4183 else if (!strcmp(name, "fscreate")) 4196 else if (!strcmp(name, "fscreate"))
4184 error = task_has_perm(current, p, PROCESS__SETFSCREATE); 4197 error = task_has_perm(current, p, PROCESS__SETFSCREATE);
4198 else if (!strcmp(name, "keycreate"))
4199 error = task_has_perm(current, p, PROCESS__SETKEYCREATE);
4185 else if (!strcmp(name, "current")) 4200 else if (!strcmp(name, "current"))
4186 error = task_has_perm(current, p, PROCESS__SETCURRENT); 4201 error = task_has_perm(current, p, PROCESS__SETCURRENT);
4187 else 4202 else
@@ -4211,7 +4226,12 @@ static int selinux_setprocattr(struct task_struct *p,
4211 tsec->exec_sid = sid; 4226 tsec->exec_sid = sid;
4212 else if (!strcmp(name, "fscreate")) 4227 else if (!strcmp(name, "fscreate"))
4213 tsec->create_sid = sid; 4228 tsec->create_sid = sid;
4214 else if (!strcmp(name, "current")) { 4229 else if (!strcmp(name, "keycreate")) {
4230 error = may_create_key(sid, p);
4231 if (error)
4232 return error;
4233 tsec->keycreate_sid = sid;
4234 } else if (!strcmp(name, "current")) {
4215 struct av_decision avd; 4235 struct av_decision avd;
4216 4236
4217 if (sid == 0) 4237 if (sid == 0)
@@ -4275,7 +4295,10 @@ static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
4275 return -ENOMEM; 4295 return -ENOMEM;
4276 4296
4277 ksec->obj = k; 4297 ksec->obj = k;
4278 ksec->sid = tsec->sid; 4298 if (tsec->keycreate_sid)
4299 ksec->sid = tsec->keycreate_sid;
4300 else
4301 ksec->sid = tsec->sid;
4279 k->security = ksec; 4302 k->security = ksec;
4280 4303
4281 return 0; 4304 return 0;
@@ -4514,10 +4537,10 @@ static __init int selinux_init(void)
4514 4537
4515#ifdef CONFIG_KEYS 4538#ifdef CONFIG_KEYS
4516 /* Add security information to initial keyrings */ 4539 /* Add security information to initial keyrings */
4517 security_key_alloc(&root_user_keyring, current, 4540 selinux_key_alloc(&root_user_keyring, current,
4518 KEY_ALLOC_NOT_IN_QUOTA); 4541 KEY_ALLOC_NOT_IN_QUOTA);
4519 security_key_alloc(&root_session_keyring, current, 4542 selinux_key_alloc(&root_session_keyring, current,
4520 KEY_ALLOC_NOT_IN_QUOTA); 4543 KEY_ALLOC_NOT_IN_QUOTA);
4521#endif 4544#endif
4522 4545
4523 return 0; 4546 return 0;
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index bc020bde6c86..e777578ccd9d 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -72,6 +72,7 @@
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")
75 S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue") 76 S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue")
76 S_(SECCLASS_MSG, MSG__SEND, "send") 77 S_(SECCLASS_MSG, MSG__SEND, "send")
77 S_(SECCLASS_MSG, MSG__RECEIVE, "receive") 78 S_(SECCLASS_MSG, MSG__RECEIVE, "receive")
@@ -248,3 +249,4 @@
248 S_(SECCLASS_KEY, KEY__SEARCH, "search") 249 S_(SECCLASS_KEY, KEY__SEARCH, "search")
249 S_(SECCLASS_KEY, KEY__LINK, "link") 250 S_(SECCLASS_KEY, KEY__LINK, "link")
250 S_(SECCLASS_KEY, KEY__SETATTR, "setattr") 251 S_(SECCLASS_KEY, KEY__SETATTR, "setattr")
252 S_(SECCLASS_KEY, KEY__CREATE, "create")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index 1205227a3a33..1e1678023b68 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -467,6 +467,7 @@
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
470 471
471#define IPC__CREATE 0x00000001UL 472#define IPC__CREATE 0x00000001UL
472#define IPC__DESTROY 0x00000002UL 473#define IPC__DESTROY 0x00000002UL
@@ -966,4 +967,4 @@
966#define KEY__SEARCH 0x00000008UL 967#define KEY__SEARCH 0x00000008UL
967#define KEY__LINK 0x00000010UL 968#define KEY__LINK 0x00000010UL
968#define KEY__SETATTR 0x00000020UL 969#define KEY__SETATTR 0x00000020UL
969 970#define KEY__CREATE 0x00000040UL
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 8f5547ad1856..191b3e4484ce 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -32,6 +32,7 @@ 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 */
35 u32 ptrace_sid; /* SID of ptrace parent */ 36 u32 ptrace_sid; /* SID of ptrace parent */
36}; 37};
37 38