diff options
-rw-r--r-- | Documentation/keys.txt | 27 | ||||
-rw-r--r-- | fs/proc/base.c | 6 | ||||
-rw-r--r-- | security/selinux/hooks.c | 35 | ||||
-rw-r--r-- | security/selinux/include/av_perm_to_string.h | 2 | ||||
-rw-r--r-- | security/selinux/include/av_permissions.h | 3 | ||||
-rw-r--r-- | security/selinux/include/objsec.h | 1 |
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 | |||
241 | controls can be applied to keys created within various contexts. This support | 241 | controls can be applied to keys created within various contexts. This support |
242 | is preliminary, and is likely to change quite significantly in the near future. | 242 | is preliminary, and is likely to change quite significantly in the near future. |
243 | Currently, all of the basic permissions explained above are provided in SELinux | 243 | Currently, all of the basic permissions explained above are provided in SELinux |
244 | as well; SE Linux is simply invoked after all basic permission checks have been | 244 | as well; SELinux is simply invoked after all basic permission checks have been |
245 | performed. | 245 | performed. |
246 | 246 | ||
247 | Each key is labeled with the same context as the task to which it belongs. | 247 | The value of the file /proc/self/attr/keycreate influences the labeling of |
248 | Typically, this is the same task that was running when the key was created. | 248 | newly-created keys. If the contents of that file correspond to an SELinux |
249 | The default keyrings are handled differently, but in a way that is very | 249 | security context, then the key will be assigned that context. Otherwise, the |
250 | intuitive: | 250 | key will be assigned the current context of the task that invoked the key |
251 | creation request. Tasks must be granted explicit permission to assign a | ||
252 | particular context to newly-created keys, using the "create" permission in the | ||
253 | key security class. | ||
251 | 254 | ||
252 | (*) The user and user session keyrings that are created when the user logs in | 255 | The default keyrings associated with users will be labeled with the default |
253 | are currently labeled with the context of the login manager. | 256 | context of the user if and only if the login programs have been instrumented to |
254 | 257 | properly initialize keycreate during the login process. Otherwise, they will | |
255 | (*) The keyrings associated with new threads are each labeled with the context | 258 | be 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 | ||
259 | Note, however, that the default keyrings associated with the root user are | 260 | Note, however, that the default keyrings associated with the root user are |
260 | labeled with the default kernel context, since they are created early in the | 261 | labeled with the default kernel context, since they are created early in the |
261 | boot process, before root has a chance to log in. | 262 | boot process, before root has a chance to log in. |
262 | 263 | ||
264 | The keyrings associated with new threads are each labeled with the context of | ||
265 | their associated thread, and both session and process keyrings are handled | ||
266 | similarly. | ||
267 | |||
263 | 268 | ||
264 | ================ | 269 | ================ |
265 | NEW PROCFS FILES | 270 | NEW 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 | }; |
280 | static struct pid_entry tid_attr_stuff[] = { | 283 | static 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. */ | ||
1103 | static 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 | ||