diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-24 08:41:41 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-24 13:07:53 -0400 |
commit | 816724e65c72a90a44fbad0ef0b59b186c85fa90 (patch) | |
tree | 421fa29aedff988e392f92780637553e275d37a0 /security | |
parent | 70ac4385a13f78bc478f26d317511893741b05bd (diff) | |
parent | d384ea691fe4ea8c2dd5b9b8d9042eb181776f18 (diff) |
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Conflicts:
fs/nfs/inode.c
fs/super.c
Fix conflicts between patch 'NFS: Split fs/nfs/inode.c' and patch
'VFS: Permit filesystem to override root dentry on mount'
Diffstat (limited to 'security')
-rw-r--r-- | security/dummy.c | 16 | ||||
-rw-r--r-- | security/inode.c | 8 | ||||
-rw-r--r-- | security/keys/key.c | 12 | ||||
-rw-r--r-- | security/keys/keyring.c | 5 | ||||
-rw-r--r-- | security/keys/process_keys.c | 57 | ||||
-rw-r--r-- | security/keys/request_key.c | 6 | ||||
-rw-r--r-- | security/keys/request_key_auth.c | 47 | ||||
-rw-r--r-- | security/selinux/hooks.c | 82 | ||||
-rw-r--r-- | security/selinux/include/av_perm_to_string.h | 6 | ||||
-rw-r--r-- | security/selinux/include/av_permissions.h | 8 | ||||
-rw-r--r-- | security/selinux/include/class_to_string.h | 1 | ||||
-rw-r--r-- | security/selinux/include/flask.h | 1 | ||||
-rw-r--r-- | security/selinux/include/objsec.h | 5 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 7 |
14 files changed, 216 insertions, 45 deletions
diff --git a/security/dummy.c b/security/dummy.c index 64f6da0f422e..c3c5493581e2 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -191,7 +191,7 @@ static int dummy_sb_kern_mount (struct super_block *sb, void *data) | |||
191 | return 0; | 191 | return 0; |
192 | } | 192 | } |
193 | 193 | ||
194 | static int dummy_sb_statfs (struct super_block *sb) | 194 | static int dummy_sb_statfs (struct dentry *dentry) |
195 | { | 195 | { |
196 | return 0; | 196 | return 0; |
197 | } | 197 | } |
@@ -516,6 +516,11 @@ static int dummy_task_setnice (struct task_struct *p, int nice) | |||
516 | return 0; | 516 | return 0; |
517 | } | 517 | } |
518 | 518 | ||
519 | static int dummy_task_setioprio (struct task_struct *p, int ioprio) | ||
520 | { | ||
521 | return 0; | ||
522 | } | ||
523 | |||
519 | static int dummy_task_setrlimit (unsigned int resource, struct rlimit *new_rlim) | 524 | static int dummy_task_setrlimit (unsigned int resource, struct rlimit *new_rlim) |
520 | { | 525 | { |
521 | return 0; | 526 | return 0; |
@@ -532,6 +537,11 @@ static int dummy_task_getscheduler (struct task_struct *p) | |||
532 | return 0; | 537 | return 0; |
533 | } | 538 | } |
534 | 539 | ||
540 | static int dummy_task_movememory (struct task_struct *p) | ||
541 | { | ||
542 | return 0; | ||
543 | } | ||
544 | |||
535 | static int dummy_task_wait (struct task_struct *p) | 545 | static int dummy_task_wait (struct task_struct *p) |
536 | { | 546 | { |
537 | return 0; | 547 | return 0; |
@@ -860,7 +870,7 @@ static int dummy_setprocattr(struct task_struct *p, char *name, void *value, siz | |||
860 | } | 870 | } |
861 | 871 | ||
862 | #ifdef CONFIG_KEYS | 872 | #ifdef CONFIG_KEYS |
863 | static inline int dummy_key_alloc(struct key *key) | 873 | static inline int dummy_key_alloc(struct key *key, struct task_struct *ctx) |
864 | { | 874 | { |
865 | return 0; | 875 | return 0; |
866 | } | 876 | } |
@@ -972,9 +982,11 @@ void security_fixup_ops (struct security_operations *ops) | |||
972 | set_to_dummy_if_null(ops, task_getsid); | 982 | set_to_dummy_if_null(ops, task_getsid); |
973 | set_to_dummy_if_null(ops, task_setgroups); | 983 | set_to_dummy_if_null(ops, task_setgroups); |
974 | set_to_dummy_if_null(ops, task_setnice); | 984 | set_to_dummy_if_null(ops, task_setnice); |
985 | set_to_dummy_if_null(ops, task_setioprio); | ||
975 | set_to_dummy_if_null(ops, task_setrlimit); | 986 | set_to_dummy_if_null(ops, task_setrlimit); |
976 | set_to_dummy_if_null(ops, task_setscheduler); | 987 | set_to_dummy_if_null(ops, task_setscheduler); |
977 | set_to_dummy_if_null(ops, task_getscheduler); | 988 | set_to_dummy_if_null(ops, task_getscheduler); |
989 | set_to_dummy_if_null(ops, task_movememory); | ||
978 | set_to_dummy_if_null(ops, task_wait); | 990 | set_to_dummy_if_null(ops, task_wait); |
979 | set_to_dummy_if_null(ops, task_kill); | 991 | set_to_dummy_if_null(ops, task_kill); |
980 | set_to_dummy_if_null(ops, task_prctl); | 992 | set_to_dummy_if_null(ops, task_prctl); |
diff --git a/security/inode.c b/security/inode.c index 8bf40625c670..98a0df500dc6 100644 --- a/security/inode.c +++ b/security/inode.c | |||
@@ -135,11 +135,11 @@ static int fill_super(struct super_block *sb, void *data, int silent) | |||
135 | return simple_fill_super(sb, SECURITYFS_MAGIC, files); | 135 | return simple_fill_super(sb, SECURITYFS_MAGIC, files); |
136 | } | 136 | } |
137 | 137 | ||
138 | static struct super_block *get_sb(struct file_system_type *fs_type, | 138 | static int get_sb(struct file_system_type *fs_type, |
139 | int flags, const char *dev_name, | 139 | int flags, const char *dev_name, |
140 | void *data) | 140 | void *data, struct vfsmount *mnt) |
141 | { | 141 | { |
142 | return get_sb_single(fs_type, flags, data, fill_super); | 142 | return get_sb_single(fs_type, flags, data, fill_super, mnt); |
143 | } | 143 | } |
144 | 144 | ||
145 | static struct file_system_type fs_type = { | 145 | static struct file_system_type fs_type = { |
diff --git a/security/keys/key.c b/security/keys/key.c index 3fdc49c6a02c..51f851557389 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -247,8 +247,8 @@ static inline void key_alloc_serial(struct key *key) | |||
247 | * instantiate the key or discard it before returning | 247 | * instantiate the key or discard it before returning |
248 | */ | 248 | */ |
249 | struct key *key_alloc(struct key_type *type, const char *desc, | 249 | struct key *key_alloc(struct key_type *type, const char *desc, |
250 | uid_t uid, gid_t gid, key_perm_t perm, | 250 | uid_t uid, gid_t gid, struct task_struct *ctx, |
251 | int not_in_quota) | 251 | key_perm_t perm, int not_in_quota) |
252 | { | 252 | { |
253 | struct key_user *user = NULL; | 253 | struct key_user *user = NULL; |
254 | struct key *key; | 254 | struct key *key; |
@@ -318,7 +318,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
318 | #endif | 318 | #endif |
319 | 319 | ||
320 | /* let the security module know about the key */ | 320 | /* let the security module know about the key */ |
321 | ret = security_key_alloc(key); | 321 | ret = security_key_alloc(key, ctx); |
322 | if (ret < 0) | 322 | if (ret < 0) |
323 | goto security_error; | 323 | goto security_error; |
324 | 324 | ||
@@ -822,7 +822,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, | |||
822 | 822 | ||
823 | /* allocate a new key */ | 823 | /* allocate a new key */ |
824 | key = key_alloc(ktype, description, current->fsuid, current->fsgid, | 824 | key = key_alloc(ktype, description, current->fsuid, current->fsgid, |
825 | perm, not_in_quota); | 825 | current, perm, not_in_quota); |
826 | if (IS_ERR(key)) { | 826 | if (IS_ERR(key)) { |
827 | key_ref = ERR_PTR(PTR_ERR(key)); | 827 | key_ref = ERR_PTR(PTR_ERR(key)); |
828 | goto error_3; | 828 | goto error_3; |
@@ -907,6 +907,10 @@ void key_revoke(struct key *key) | |||
907 | * it */ | 907 | * it */ |
908 | down_write(&key->sem); | 908 | down_write(&key->sem); |
909 | set_bit(KEY_FLAG_REVOKED, &key->flags); | 909 | set_bit(KEY_FLAG_REVOKED, &key->flags); |
910 | |||
911 | if (key->type->revoke) | ||
912 | key->type->revoke(key); | ||
913 | |||
910 | up_write(&key->sem); | 914 | up_write(&key->sem); |
911 | 915 | ||
912 | } /* end key_revoke() */ | 916 | } /* end key_revoke() */ |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index bffa924c1f88..1357207fc9df 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -240,13 +240,14 @@ static long keyring_read(const struct key *keyring, | |||
240 | * allocate a keyring and link into the destination keyring | 240 | * allocate a keyring and link into the destination keyring |
241 | */ | 241 | */ |
242 | struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, | 242 | struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, |
243 | int not_in_quota, struct key *dest) | 243 | struct task_struct *ctx, int not_in_quota, |
244 | struct key *dest) | ||
244 | { | 245 | { |
245 | struct key *keyring; | 246 | struct key *keyring; |
246 | int ret; | 247 | int ret; |
247 | 248 | ||
248 | keyring = key_alloc(&key_type_keyring, description, | 249 | keyring = key_alloc(&key_type_keyring, description, |
249 | uid, gid, | 250 | uid, gid, ctx, |
250 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, | 251 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, |
251 | not_in_quota); | 252 | not_in_quota); |
252 | 253 | ||
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 217a0bef3c82..4d9825f9962c 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -67,7 +67,8 @@ struct key root_session_keyring = { | |||
67 | /* | 67 | /* |
68 | * allocate the keyrings to be associated with a UID | 68 | * allocate the keyrings to be associated with a UID |
69 | */ | 69 | */ |
70 | int alloc_uid_keyring(struct user_struct *user) | 70 | int alloc_uid_keyring(struct user_struct *user, |
71 | struct task_struct *ctx) | ||
71 | { | 72 | { |
72 | struct key *uid_keyring, *session_keyring; | 73 | struct key *uid_keyring, *session_keyring; |
73 | char buf[20]; | 74 | char buf[20]; |
@@ -76,7 +77,7 @@ int alloc_uid_keyring(struct user_struct *user) | |||
76 | /* concoct a default session keyring */ | 77 | /* concoct a default session keyring */ |
77 | sprintf(buf, "_uid_ses.%u", user->uid); | 78 | sprintf(buf, "_uid_ses.%u", user->uid); |
78 | 79 | ||
79 | session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, NULL); | 80 | session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0, NULL); |
80 | if (IS_ERR(session_keyring)) { | 81 | if (IS_ERR(session_keyring)) { |
81 | ret = PTR_ERR(session_keyring); | 82 | ret = PTR_ERR(session_keyring); |
82 | goto error; | 83 | goto error; |
@@ -86,7 +87,7 @@ int alloc_uid_keyring(struct user_struct *user) | |||
86 | * keyring */ | 87 | * keyring */ |
87 | sprintf(buf, "_uid.%u", user->uid); | 88 | sprintf(buf, "_uid.%u", user->uid); |
88 | 89 | ||
89 | uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 0, | 90 | uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0, |
90 | session_keyring); | 91 | session_keyring); |
91 | if (IS_ERR(uid_keyring)) { | 92 | if (IS_ERR(uid_keyring)) { |
92 | key_put(session_keyring); | 93 | key_put(session_keyring); |
@@ -143,7 +144,7 @@ int install_thread_keyring(struct task_struct *tsk) | |||
143 | 144 | ||
144 | sprintf(buf, "_tid.%u", tsk->pid); | 145 | sprintf(buf, "_tid.%u", tsk->pid); |
145 | 146 | ||
146 | keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); | 147 | keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL); |
147 | if (IS_ERR(keyring)) { | 148 | if (IS_ERR(keyring)) { |
148 | ret = PTR_ERR(keyring); | 149 | ret = PTR_ERR(keyring); |
149 | goto error; | 150 | goto error; |
@@ -177,7 +178,7 @@ int install_process_keyring(struct task_struct *tsk) | |||
177 | if (!tsk->signal->process_keyring) { | 178 | if (!tsk->signal->process_keyring) { |
178 | sprintf(buf, "_pid.%u", tsk->tgid); | 179 | sprintf(buf, "_pid.%u", tsk->tgid); |
179 | 180 | ||
180 | keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); | 181 | keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL); |
181 | if (IS_ERR(keyring)) { | 182 | if (IS_ERR(keyring)) { |
182 | ret = PTR_ERR(keyring); | 183 | ret = PTR_ERR(keyring); |
183 | goto error; | 184 | goto error; |
@@ -217,7 +218,7 @@ static int install_session_keyring(struct task_struct *tsk, | |||
217 | if (!keyring) { | 218 | if (!keyring) { |
218 | sprintf(buf, "_ses.%u", tsk->tgid); | 219 | sprintf(buf, "_ses.%u", tsk->tgid); |
219 | 220 | ||
220 | keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL); | 221 | keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL); |
221 | if (IS_ERR(keyring)) | 222 | if (IS_ERR(keyring)) |
222 | return PTR_ERR(keyring); | 223 | return PTR_ERR(keyring); |
223 | } | 224 | } |
@@ -390,6 +391,8 @@ key_ref_t search_process_keyrings(struct key_type *type, | |||
390 | struct request_key_auth *rka; | 391 | struct request_key_auth *rka; |
391 | key_ref_t key_ref, ret, err; | 392 | key_ref_t key_ref, ret, err; |
392 | 393 | ||
394 | might_sleep(); | ||
395 | |||
393 | /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were | 396 | /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were |
394 | * searchable, but we failed to find a key or we found a negative key; | 397 | * searchable, but we failed to find a key or we found a negative key; |
395 | * otherwise we want to return a sample error (probably -EACCES) if | 398 | * otherwise we want to return a sample error (probably -EACCES) if |
@@ -495,27 +498,35 @@ key_ref_t search_process_keyrings(struct key_type *type, | |||
495 | */ | 498 | */ |
496 | if (context->request_key_auth && | 499 | if (context->request_key_auth && |
497 | context == current && | 500 | context == current && |
498 | type != &key_type_request_key_auth && | 501 | type != &key_type_request_key_auth |
499 | key_validate(context->request_key_auth) == 0 | ||
500 | ) { | 502 | ) { |
501 | rka = context->request_key_auth->payload.data; | 503 | /* defend against the auth key being revoked */ |
504 | down_read(&context->request_key_auth->sem); | ||
502 | 505 | ||
503 | key_ref = search_process_keyrings(type, description, match, | 506 | if (key_validate(context->request_key_auth) == 0) { |
504 | rka->context); | 507 | rka = context->request_key_auth->payload.data; |
505 | 508 | ||
506 | if (!IS_ERR(key_ref)) | 509 | key_ref = search_process_keyrings(type, description, |
507 | goto found; | 510 | match, rka->context); |
508 | 511 | ||
509 | switch (PTR_ERR(key_ref)) { | 512 | up_read(&context->request_key_auth->sem); |
510 | case -EAGAIN: /* no key */ | 513 | |
511 | if (ret) | 514 | if (!IS_ERR(key_ref)) |
515 | goto found; | ||
516 | |||
517 | switch (PTR_ERR(key_ref)) { | ||
518 | case -EAGAIN: /* no key */ | ||
519 | if (ret) | ||
520 | break; | ||
521 | case -ENOKEY: /* negative key */ | ||
522 | ret = key_ref; | ||
512 | break; | 523 | break; |
513 | case -ENOKEY: /* negative key */ | 524 | default: |
514 | ret = key_ref; | 525 | err = key_ref; |
515 | break; | 526 | break; |
516 | default: | 527 | } |
517 | err = key_ref; | 528 | } else { |
518 | break; | 529 | up_read(&context->request_key_auth->sem); |
519 | } | 530 | } |
520 | } | 531 | } |
521 | 532 | ||
@@ -717,7 +728,7 @@ long join_session_keyring(const char *name) | |||
717 | keyring = find_keyring_by_name(name, 0); | 728 | keyring = find_keyring_by_name(name, 0); |
718 | if (PTR_ERR(keyring) == -ENOKEY) { | 729 | if (PTR_ERR(keyring) == -ENOKEY) { |
719 | /* not found - try and create a new one */ | 730 | /* not found - try and create a new one */ |
720 | keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); | 731 | keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk, 0, NULL); |
721 | if (IS_ERR(keyring)) { | 732 | if (IS_ERR(keyring)) { |
722 | ret = PTR_ERR(keyring); | 733 | ret = PTR_ERR(keyring); |
723 | goto error2; | 734 | goto error2; |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index f030a0ccbb93..eab66a06ca53 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -48,7 +48,8 @@ static int call_sbin_request_key(struct key *key, | |||
48 | /* allocate a new session keyring */ | 48 | /* allocate a new session keyring */ |
49 | sprintf(desc, "_req.%u", key->serial); | 49 | sprintf(desc, "_req.%u", key->serial); |
50 | 50 | ||
51 | keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL); | 51 | keyring = keyring_alloc(desc, current->fsuid, current->fsgid, |
52 | current, 1, NULL); | ||
52 | if (IS_ERR(keyring)) { | 53 | if (IS_ERR(keyring)) { |
53 | ret = PTR_ERR(keyring); | 54 | ret = PTR_ERR(keyring); |
54 | goto error_alloc; | 55 | goto error_alloc; |
@@ -137,7 +138,8 @@ static struct key *__request_key_construction(struct key_type *type, | |||
137 | 138 | ||
138 | /* create a key and add it to the queue */ | 139 | /* create a key and add it to the queue */ |
139 | key = key_alloc(type, description, | 140 | key = key_alloc(type, description, |
140 | current->fsuid, current->fsgid, KEY_POS_ALL, 0); | 141 | current->fsuid, current->fsgid, |
142 | current, KEY_POS_ALL, 0); | ||
141 | if (IS_ERR(key)) | 143 | if (IS_ERR(key)) |
142 | goto alloc_failed; | 144 | goto alloc_failed; |
143 | 145 | ||
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index cce6ba6b0323..cb9817ced3fd 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | static int request_key_auth_instantiate(struct key *, const void *, size_t); | 21 | static int request_key_auth_instantiate(struct key *, const void *, size_t); |
22 | static void request_key_auth_describe(const struct key *, struct seq_file *); | 22 | static void request_key_auth_describe(const struct key *, struct seq_file *); |
23 | static void request_key_auth_revoke(struct key *); | ||
23 | static void request_key_auth_destroy(struct key *); | 24 | static void request_key_auth_destroy(struct key *); |
24 | static long request_key_auth_read(const struct key *, char __user *, size_t); | 25 | static long request_key_auth_read(const struct key *, char __user *, size_t); |
25 | 26 | ||
@@ -31,6 +32,7 @@ struct key_type key_type_request_key_auth = { | |||
31 | .def_datalen = sizeof(struct request_key_auth), | 32 | .def_datalen = sizeof(struct request_key_auth), |
32 | .instantiate = request_key_auth_instantiate, | 33 | .instantiate = request_key_auth_instantiate, |
33 | .describe = request_key_auth_describe, | 34 | .describe = request_key_auth_describe, |
35 | .revoke = request_key_auth_revoke, | ||
34 | .destroy = request_key_auth_destroy, | 36 | .destroy = request_key_auth_destroy, |
35 | .read = request_key_auth_read, | 37 | .read = request_key_auth_read, |
36 | }; | 38 | }; |
@@ -93,6 +95,24 @@ static long request_key_auth_read(const struct key *key, | |||
93 | 95 | ||
94 | /*****************************************************************************/ | 96 | /*****************************************************************************/ |
95 | /* | 97 | /* |
98 | * handle revocation of an authorisation token key | ||
99 | * - called with the key sem write-locked | ||
100 | */ | ||
101 | static void request_key_auth_revoke(struct key *key) | ||
102 | { | ||
103 | struct request_key_auth *rka = key->payload.data; | ||
104 | |||
105 | kenter("{%d}", key->serial); | ||
106 | |||
107 | if (rka->context) { | ||
108 | put_task_struct(rka->context); | ||
109 | rka->context = NULL; | ||
110 | } | ||
111 | |||
112 | } /* end request_key_auth_revoke() */ | ||
113 | |||
114 | /*****************************************************************************/ | ||
115 | /* | ||
96 | * destroy an instantiation authorisation token key | 116 | * destroy an instantiation authorisation token key |
97 | */ | 117 | */ |
98 | static void request_key_auth_destroy(struct key *key) | 118 | static void request_key_auth_destroy(struct key *key) |
@@ -101,6 +121,11 @@ static void request_key_auth_destroy(struct key *key) | |||
101 | 121 | ||
102 | kenter("{%d}", key->serial); | 122 | kenter("{%d}", key->serial); |
103 | 123 | ||
124 | if (rka->context) { | ||
125 | put_task_struct(rka->context); | ||
126 | rka->context = NULL; | ||
127 | } | ||
128 | |||
104 | key_put(rka->target_key); | 129 | key_put(rka->target_key); |
105 | kfree(rka); | 130 | kfree(rka); |
106 | 131 | ||
@@ -131,14 +156,26 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) | |||
131 | * another process */ | 156 | * another process */ |
132 | if (current->request_key_auth) { | 157 | if (current->request_key_auth) { |
133 | /* it is - use that instantiation context here too */ | 158 | /* it is - use that instantiation context here too */ |
159 | down_read(¤t->request_key_auth->sem); | ||
160 | |||
161 | /* if the auth key has been revoked, then the key we're | ||
162 | * servicing is already instantiated */ | ||
163 | if (test_bit(KEY_FLAG_REVOKED, | ||
164 | ¤t->request_key_auth->flags)) | ||
165 | goto auth_key_revoked; | ||
166 | |||
134 | irka = current->request_key_auth->payload.data; | 167 | irka = current->request_key_auth->payload.data; |
135 | rka->context = irka->context; | 168 | rka->context = irka->context; |
136 | rka->pid = irka->pid; | 169 | rka->pid = irka->pid; |
170 | get_task_struct(rka->context); | ||
171 | |||
172 | up_read(¤t->request_key_auth->sem); | ||
137 | } | 173 | } |
138 | else { | 174 | else { |
139 | /* it isn't - use this process as the context */ | 175 | /* it isn't - use this process as the context */ |
140 | rka->context = current; | 176 | rka->context = current; |
141 | rka->pid = current->pid; | 177 | rka->pid = current->pid; |
178 | get_task_struct(rka->context); | ||
142 | } | 179 | } |
143 | 180 | ||
144 | rka->target_key = key_get(target); | 181 | rka->target_key = key_get(target); |
@@ -148,7 +185,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) | |||
148 | sprintf(desc, "%x", target->serial); | 185 | sprintf(desc, "%x", target->serial); |
149 | 186 | ||
150 | authkey = key_alloc(&key_type_request_key_auth, desc, | 187 | authkey = key_alloc(&key_type_request_key_auth, desc, |
151 | current->fsuid, current->fsgid, | 188 | current->fsuid, current->fsgid, current, |
152 | KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | | 189 | KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | |
153 | KEY_USR_VIEW, 1); | 190 | KEY_USR_VIEW, 1); |
154 | if (IS_ERR(authkey)) { | 191 | if (IS_ERR(authkey)) { |
@@ -161,9 +198,15 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info) | |||
161 | if (ret < 0) | 198 | if (ret < 0) |
162 | goto error_inst; | 199 | goto error_inst; |
163 | 200 | ||
164 | kleave(" = {%d})", authkey->serial); | 201 | kleave(" = {%d}", authkey->serial); |
165 | return authkey; | 202 | return authkey; |
166 | 203 | ||
204 | auth_key_revoked: | ||
205 | up_read(¤t->request_key_auth->sem); | ||
206 | kfree(rka); | ||
207 | kleave("= -EKEYREVOKED"); | ||
208 | return ERR_PTR(-EKEYREVOKED); | ||
209 | |||
167 | error_inst: | 210 | error_inst: |
168 | key_revoke(authkey); | 211 | key_revoke(authkey); |
169 | key_put(authkey); | 212 | key_put(authkey); |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 54adc9d31e92..79c16e31c884 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1903,13 +1903,13 @@ static int selinux_sb_kern_mount(struct super_block *sb, void *data) | |||
1903 | return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad); | 1903 | return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad); |
1904 | } | 1904 | } |
1905 | 1905 | ||
1906 | static int selinux_sb_statfs(struct super_block *sb) | 1906 | static int selinux_sb_statfs(struct dentry *dentry) |
1907 | { | 1907 | { |
1908 | struct avc_audit_data ad; | 1908 | struct avc_audit_data ad; |
1909 | 1909 | ||
1910 | AVC_AUDIT_DATA_INIT(&ad,FS); | 1910 | AVC_AUDIT_DATA_INIT(&ad,FS); |
1911 | ad.u.fs.dentry = sb->s_root; | 1911 | ad.u.fs.dentry = dentry->d_sb->s_root; |
1912 | return superblock_has_perm(current, sb, FILESYSTEM__GETATTR, &ad); | 1912 | return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad); |
1913 | } | 1913 | } |
1914 | 1914 | ||
1915 | static int selinux_mount(char * dev_name, | 1915 | static int selinux_mount(char * dev_name, |
@@ -2645,6 +2645,11 @@ static int selinux_task_setnice(struct task_struct *p, int nice) | |||
2645 | return task_has_perm(current,p, PROCESS__SETSCHED); | 2645 | return task_has_perm(current,p, PROCESS__SETSCHED); |
2646 | } | 2646 | } |
2647 | 2647 | ||
2648 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) | ||
2649 | { | ||
2650 | return task_has_perm(current, p, PROCESS__SETSCHED); | ||
2651 | } | ||
2652 | |||
2648 | static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) | 2653 | static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) |
2649 | { | 2654 | { |
2650 | struct rlimit *old_rlim = current->signal->rlim + resource; | 2655 | struct rlimit *old_rlim = current->signal->rlim + resource; |
@@ -2674,6 +2679,11 @@ static int selinux_task_getscheduler(struct task_struct *p) | |||
2674 | return task_has_perm(current, p, PROCESS__GETSCHED); | 2679 | return task_has_perm(current, p, PROCESS__GETSCHED); |
2675 | } | 2680 | } |
2676 | 2681 | ||
2682 | static int selinux_task_movememory(struct task_struct *p) | ||
2683 | { | ||
2684 | return task_has_perm(current, p, PROCESS__SETSCHED); | ||
2685 | } | ||
2686 | |||
2677 | static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig) | 2687 | static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig) |
2678 | { | 2688 | { |
2679 | u32 perm; | 2689 | u32 perm; |
@@ -4252,6 +4262,57 @@ static int selinux_setprocattr(struct task_struct *p, | |||
4252 | return size; | 4262 | return size; |
4253 | } | 4263 | } |
4254 | 4264 | ||
4265 | #ifdef CONFIG_KEYS | ||
4266 | |||
4267 | static int selinux_key_alloc(struct key *k, struct task_struct *tsk) | ||
4268 | { | ||
4269 | struct task_security_struct *tsec = tsk->security; | ||
4270 | struct key_security_struct *ksec; | ||
4271 | |||
4272 | ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL); | ||
4273 | if (!ksec) | ||
4274 | return -ENOMEM; | ||
4275 | |||
4276 | ksec->obj = k; | ||
4277 | ksec->sid = tsec->sid; | ||
4278 | k->security = ksec; | ||
4279 | |||
4280 | return 0; | ||
4281 | } | ||
4282 | |||
4283 | static void selinux_key_free(struct key *k) | ||
4284 | { | ||
4285 | struct key_security_struct *ksec = k->security; | ||
4286 | |||
4287 | k->security = NULL; | ||
4288 | kfree(ksec); | ||
4289 | } | ||
4290 | |||
4291 | static int selinux_key_permission(key_ref_t key_ref, | ||
4292 | struct task_struct *ctx, | ||
4293 | key_perm_t perm) | ||
4294 | { | ||
4295 | struct key *key; | ||
4296 | struct task_security_struct *tsec; | ||
4297 | struct key_security_struct *ksec; | ||
4298 | |||
4299 | key = key_ref_to_ptr(key_ref); | ||
4300 | |||
4301 | tsec = ctx->security; | ||
4302 | ksec = key->security; | ||
4303 | |||
4304 | /* if no specific permissions are requested, we skip the | ||
4305 | permission check. No serious, additional covert channels | ||
4306 | appear to be created. */ | ||
4307 | if (perm == 0) | ||
4308 | return 0; | ||
4309 | |||
4310 | return avc_has_perm(tsec->sid, ksec->sid, | ||
4311 | SECCLASS_KEY, perm, NULL); | ||
4312 | } | ||
4313 | |||
4314 | #endif | ||
4315 | |||
4255 | static struct security_operations selinux_ops = { | 4316 | static struct security_operations selinux_ops = { |
4256 | .ptrace = selinux_ptrace, | 4317 | .ptrace = selinux_ptrace, |
4257 | .capget = selinux_capget, | 4318 | .capget = selinux_capget, |
@@ -4332,9 +4393,11 @@ static struct security_operations selinux_ops = { | |||
4332 | .task_getsid = selinux_task_getsid, | 4393 | .task_getsid = selinux_task_getsid, |
4333 | .task_setgroups = selinux_task_setgroups, | 4394 | .task_setgroups = selinux_task_setgroups, |
4334 | .task_setnice = selinux_task_setnice, | 4395 | .task_setnice = selinux_task_setnice, |
4396 | .task_setioprio = selinux_task_setioprio, | ||
4335 | .task_setrlimit = selinux_task_setrlimit, | 4397 | .task_setrlimit = selinux_task_setrlimit, |
4336 | .task_setscheduler = selinux_task_setscheduler, | 4398 | .task_setscheduler = selinux_task_setscheduler, |
4337 | .task_getscheduler = selinux_task_getscheduler, | 4399 | .task_getscheduler = selinux_task_getscheduler, |
4400 | .task_movememory = selinux_task_movememory, | ||
4338 | .task_kill = selinux_task_kill, | 4401 | .task_kill = selinux_task_kill, |
4339 | .task_wait = selinux_task_wait, | 4402 | .task_wait = selinux_task_wait, |
4340 | .task_prctl = selinux_task_prctl, | 4403 | .task_prctl = selinux_task_prctl, |
@@ -4406,6 +4469,12 @@ static struct security_operations selinux_ops = { | |||
4406 | .xfrm_state_delete_security = selinux_xfrm_state_delete, | 4469 | .xfrm_state_delete_security = selinux_xfrm_state_delete, |
4407 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, | 4470 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, |
4408 | #endif | 4471 | #endif |
4472 | |||
4473 | #ifdef CONFIG_KEYS | ||
4474 | .key_alloc = selinux_key_alloc, | ||
4475 | .key_free = selinux_key_free, | ||
4476 | .key_permission = selinux_key_permission, | ||
4477 | #endif | ||
4409 | }; | 4478 | }; |
4410 | 4479 | ||
4411 | static __init int selinux_init(void) | 4480 | static __init int selinux_init(void) |
@@ -4441,6 +4510,13 @@ static __init int selinux_init(void) | |||
4441 | } else { | 4510 | } else { |
4442 | printk(KERN_INFO "SELinux: Starting in permissive mode\n"); | 4511 | printk(KERN_INFO "SELinux: Starting in permissive mode\n"); |
4443 | } | 4512 | } |
4513 | |||
4514 | #ifdef CONFIG_KEYS | ||
4515 | /* Add security information to initial keyrings */ | ||
4516 | security_key_alloc(&root_user_keyring, current); | ||
4517 | security_key_alloc(&root_session_keyring, current); | ||
4518 | #endif | ||
4519 | |||
4444 | return 0; | 4520 | return 0; |
4445 | } | 4521 | } |
4446 | 4522 | ||
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index 70ee65a58817..bc020bde6c86 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h | |||
@@ -242,3 +242,9 @@ | |||
242 | S_(SECCLASS_PACKET, PACKET__SEND, "send") | 242 | S_(SECCLASS_PACKET, PACKET__SEND, "send") |
243 | S_(SECCLASS_PACKET, PACKET__RECV, "recv") | 243 | S_(SECCLASS_PACKET, PACKET__RECV, "recv") |
244 | S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto") | 244 | S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto") |
245 | S_(SECCLASS_KEY, KEY__VIEW, "view") | ||
246 | S_(SECCLASS_KEY, KEY__READ, "read") | ||
247 | S_(SECCLASS_KEY, KEY__WRITE, "write") | ||
248 | S_(SECCLASS_KEY, KEY__SEARCH, "search") | ||
249 | S_(SECCLASS_KEY, KEY__LINK, "link") | ||
250 | S_(SECCLASS_KEY, KEY__SETATTR, "setattr") | ||
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index 1d9cf3d306bc..1205227a3a33 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h | |||
@@ -959,3 +959,11 @@ | |||
959 | #define PACKET__SEND 0x00000001UL | 959 | #define PACKET__SEND 0x00000001UL |
960 | #define PACKET__RECV 0x00000002UL | 960 | #define PACKET__RECV 0x00000002UL |
961 | #define PACKET__RELABELTO 0x00000004UL | 961 | #define PACKET__RELABELTO 0x00000004UL |
962 | |||
963 | #define KEY__VIEW 0x00000001UL | ||
964 | #define KEY__READ 0x00000002UL | ||
965 | #define KEY__WRITE 0x00000004UL | ||
966 | #define KEY__SEARCH 0x00000008UL | ||
967 | #define KEY__LINK 0x00000010UL | ||
968 | #define KEY__SETATTR 0x00000020UL | ||
969 | |||
diff --git a/security/selinux/include/class_to_string.h b/security/selinux/include/class_to_string.h index 3aec75fee4f7..24303b61309f 100644 --- a/security/selinux/include/class_to_string.h +++ b/security/selinux/include/class_to_string.h | |||
@@ -60,3 +60,4 @@ | |||
60 | S_("netlink_kobject_uevent_socket") | 60 | S_("netlink_kobject_uevent_socket") |
61 | S_("appletalk_socket") | 61 | S_("appletalk_socket") |
62 | S_("packet") | 62 | S_("packet") |
63 | S_("key") | ||
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h index a0eb9e281d18..95887aed2a68 100644 --- a/security/selinux/include/flask.h +++ b/security/selinux/include/flask.h | |||
@@ -62,6 +62,7 @@ | |||
62 | #define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55 | 62 | #define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55 |
63 | #define SECCLASS_APPLETALK_SOCKET 56 | 63 | #define SECCLASS_APPLETALK_SOCKET 56 |
64 | #define SECCLASS_PACKET 57 | 64 | #define SECCLASS_PACKET 57 |
65 | #define SECCLASS_KEY 58 | ||
65 | 66 | ||
66 | /* | 67 | /* |
67 | * Security identifier indices for initial entities | 68 | * Security identifier indices for initial entities |
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 54c030778882..8f5547ad1856 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
@@ -99,6 +99,11 @@ struct sk_security_struct { | |||
99 | u32 peer_sid; /* SID of peer */ | 99 | u32 peer_sid; /* SID of peer */ |
100 | }; | 100 | }; |
101 | 101 | ||
102 | struct key_security_struct { | ||
103 | struct key *obj; /* back pointer */ | ||
104 | u32 sid; /* SID of key */ | ||
105 | }; | ||
106 | |||
102 | extern unsigned int selinux_checkreqprot; | 107 | extern unsigned int selinux_checkreqprot; |
103 | 108 | ||
104 | #endif /* _SELINUX_OBJSEC_H_ */ | 109 | #endif /* _SELINUX_OBJSEC_H_ */ |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 2e73d3279f2d..7029bbc9bef8 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -1345,10 +1345,11 @@ err: | |||
1345 | goto out; | 1345 | goto out; |
1346 | } | 1346 | } |
1347 | 1347 | ||
1348 | static struct super_block *sel_get_sb(struct file_system_type *fs_type, | 1348 | static int sel_get_sb(struct file_system_type *fs_type, |
1349 | int flags, const char *dev_name, void *data) | 1349 | int flags, const char *dev_name, void *data, |
1350 | struct vfsmount *mnt) | ||
1350 | { | 1351 | { |
1351 | return get_sb_single(fs_type, flags, data, sel_fill_super); | 1352 | return get_sb_single(fs_type, flags, data, sel_fill_super, mnt); |
1352 | } | 1353 | } |
1353 | 1354 | ||
1354 | static struct file_system_type sel_fs_type = { | 1355 | static struct file_system_type sel_fs_type = { |