aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
authorJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-06-28 14:06:39 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-06-28 14:06:39 -0400
commitf28e71617ddaf2483e3e5c5237103484a303743f (patch)
tree67627d2d8ddbf6a4449371e9261d796c013b1fa1 /security/keys
parentdc6a78f1af10d28fb8c395034ae1e099b85c05b0 (diff)
parenta39727f212426b9d5f9267b3318a2afaf9922d3b (diff)
Merge ../linux-2.6/
Conflicts: drivers/scsi/aacraid/comminit.c Fixed up by removing the now renamed CONFIG_IOMMU option from aacraid Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/internal.h3
-rw-r--r--security/keys/key.c57
-rw-r--r--security/keys/keyctl.c61
-rw-r--r--security/keys/keyring.c25
-rw-r--r--security/keys/proc.c7
-rw-r--r--security/keys/process_keys.c24
-rw-r--r--security/keys/request_key.c36
-rw-r--r--security/keys/request_key_auth.c2
-rw-r--r--security/keys/user_defined.c25
9 files changed, 176 insertions, 64 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h
index e066e6057955..3c2877f0663e 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -99,7 +99,8 @@ extern int install_process_keyring(struct task_struct *tsk);
99extern struct key *request_key_and_link(struct key_type *type, 99extern struct key *request_key_and_link(struct key_type *type,
100 const char *description, 100 const char *description,
101 const char *callout_info, 101 const char *callout_info,
102 struct key *dest_keyring); 102 struct key *dest_keyring,
103 unsigned long flags);
103 104
104/* 105/*
105 * request_key authorisation 106 * request_key authorisation
diff --git a/security/keys/key.c b/security/keys/key.c
index 51f851557389..80de8c3e9cc3 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -11,15 +11,16 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/poison.h>
14#include <linux/sched.h> 15#include <linux/sched.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/security.h> 17#include <linux/security.h>
17#include <linux/workqueue.h> 18#include <linux/workqueue.h>
19#include <linux/random.h>
18#include <linux/err.h> 20#include <linux/err.h>
19#include "internal.h" 21#include "internal.h"
20 22
21static kmem_cache_t *key_jar; 23static kmem_cache_t *key_jar;
22static key_serial_t key_serial_next = 3;
23struct rb_root key_serial_tree; /* tree of keys indexed by serial */ 24struct rb_root key_serial_tree; /* tree of keys indexed by serial */
24DEFINE_SPINLOCK(key_serial_lock); 25DEFINE_SPINLOCK(key_serial_lock);
25 26
@@ -169,22 +170,23 @@ static void __init __key_insert_serial(struct key *key)
169/*****************************************************************************/ 170/*****************************************************************************/
170/* 171/*
171 * assign a key the next unique serial number 172 * assign a key the next unique serial number
172 * - we work through all the serial numbers between 2 and 2^31-1 in turn and 173 * - these are assigned randomly to avoid security issues through covert
173 * then wrap 174 * channel problems
174 */ 175 */
175static inline void key_alloc_serial(struct key *key) 176static inline void key_alloc_serial(struct key *key)
176{ 177{
177 struct rb_node *parent, **p; 178 struct rb_node *parent, **p;
178 struct key *xkey; 179 struct key *xkey;
179 180
180 spin_lock(&key_serial_lock); 181 /* propose a random serial number and look for a hole for it in the
181
182 /* propose a likely serial number and look for a hole for it in the
183 * serial number tree */ 182 * serial number tree */
184 key->serial = key_serial_next; 183 do {
185 if (key->serial < 3) 184 get_random_bytes(&key->serial, sizeof(key->serial));
186 key->serial = 3; 185
187 key_serial_next = key->serial + 1; 186 key->serial >>= 1; /* negative numbers are not permitted */
187 } while (key->serial < 3);
188
189 spin_lock(&key_serial_lock);
188 190
189 parent = NULL; 191 parent = NULL;
190 p = &key_serial_tree.rb_node; 192 p = &key_serial_tree.rb_node;
@@ -204,12 +206,11 @@ static inline void key_alloc_serial(struct key *key)
204 206
205 /* we found a key with the proposed serial number - walk the tree from 207 /* we found a key with the proposed serial number - walk the tree from
206 * that point looking for the next unused serial number */ 208 * that point looking for the next unused serial number */
207 serial_exists: 209serial_exists:
208 for (;;) { 210 for (;;) {
209 key->serial = key_serial_next; 211 key->serial++;
210 if (key->serial < 2) 212 if (key->serial < 2)
211 key->serial = 2; 213 key->serial = 2;
212 key_serial_next = key->serial + 1;
213 214
214 if (!rb_parent(parent)) 215 if (!rb_parent(parent))
215 p = &key_serial_tree.rb_node; 216 p = &key_serial_tree.rb_node;
@@ -228,7 +229,7 @@ static inline void key_alloc_serial(struct key *key)
228 } 229 }
229 230
230 /* we've found a suitable hole - arrange for this key to occupy it */ 231 /* we've found a suitable hole - arrange for this key to occupy it */
231 insert_here: 232insert_here:
232 rb_link_node(&key->serial_node, parent, p); 233 rb_link_node(&key->serial_node, parent, p);
233 rb_insert_color(&key->serial_node, &key_serial_tree); 234 rb_insert_color(&key->serial_node, &key_serial_tree);
234 235
@@ -248,7 +249,7 @@ static inline void key_alloc_serial(struct key *key)
248 */ 249 */
249struct key *key_alloc(struct key_type *type, const char *desc, 250struct key *key_alloc(struct key_type *type, const char *desc,
250 uid_t uid, gid_t gid, struct task_struct *ctx, 251 uid_t uid, gid_t gid, struct task_struct *ctx,
251 key_perm_t perm, int not_in_quota) 252 key_perm_t perm, unsigned long flags)
252{ 253{
253 struct key_user *user = NULL; 254 struct key_user *user = NULL;
254 struct key *key; 255 struct key *key;
@@ -269,12 +270,14 @@ struct key *key_alloc(struct key_type *type, const char *desc,
269 270
270 /* check that the user's quota permits allocation of another key and 271 /* check that the user's quota permits allocation of another key and
271 * its description */ 272 * its description */
272 if (!not_in_quota) { 273 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
273 spin_lock(&user->lock); 274 spin_lock(&user->lock);
274 if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS || 275 if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) {
275 user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES 276 if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS ||
276 ) 277 user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES
277 goto no_quota; 278 )
279 goto no_quota;
280 }
278 281
279 user->qnkeys++; 282 user->qnkeys++;
280 user->qnbytes += quotalen; 283 user->qnbytes += quotalen;
@@ -308,7 +311,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
308 key->payload.data = NULL; 311 key->payload.data = NULL;
309 key->security = NULL; 312 key->security = NULL;
310 313
311 if (!not_in_quota) 314 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
312 key->flags |= 1 << KEY_FLAG_IN_QUOTA; 315 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
313 316
314 memset(&key->type_data, 0, sizeof(key->type_data)); 317 memset(&key->type_data, 0, sizeof(key->type_data));
@@ -318,7 +321,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
318#endif 321#endif
319 322
320 /* let the security module know about the key */ 323 /* let the security module know about the key */
321 ret = security_key_alloc(key, ctx); 324 ret = security_key_alloc(key, ctx, flags);
322 if (ret < 0) 325 if (ret < 0)
323 goto security_error; 326 goto security_error;
324 327
@@ -332,7 +335,7 @@ error:
332security_error: 335security_error:
333 kfree(key->description); 336 kfree(key->description);
334 kmem_cache_free(key_jar, key); 337 kmem_cache_free(key_jar, key);
335 if (!not_in_quota) { 338 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
336 spin_lock(&user->lock); 339 spin_lock(&user->lock);
337 user->qnkeys--; 340 user->qnkeys--;
338 user->qnbytes -= quotalen; 341 user->qnbytes -= quotalen;
@@ -345,7 +348,7 @@ security_error:
345no_memory_3: 348no_memory_3:
346 kmem_cache_free(key_jar, key); 349 kmem_cache_free(key_jar, key);
347no_memory_2: 350no_memory_2:
348 if (!not_in_quota) { 351 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
349 spin_lock(&user->lock); 352 spin_lock(&user->lock);
350 user->qnkeys--; 353 user->qnkeys--;
351 user->qnbytes -= quotalen; 354 user->qnbytes -= quotalen;
@@ -761,7 +764,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
761 const char *description, 764 const char *description,
762 const void *payload, 765 const void *payload,
763 size_t plen, 766 size_t plen,
764 int not_in_quota) 767 unsigned long flags)
765{ 768{
766 struct key_type *ktype; 769 struct key_type *ktype;
767 struct key *keyring, *key = NULL; 770 struct key *keyring, *key = NULL;
@@ -822,7 +825,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
822 825
823 /* allocate a new key */ 826 /* allocate a new key */
824 key = key_alloc(ktype, description, current->fsuid, current->fsgid, 827 key = key_alloc(ktype, description, current->fsuid, current->fsgid,
825 current, perm, not_in_quota); 828 current, perm, flags);
826 if (IS_ERR(key)) { 829 if (IS_ERR(key)) {
827 key_ref = ERR_PTR(PTR_ERR(key)); 830 key_ref = ERR_PTR(PTR_ERR(key));
828 goto error_3; 831 goto error_3;
@@ -986,7 +989,7 @@ void unregister_key_type(struct key_type *ktype)
986 if (key->type == ktype) { 989 if (key->type == ktype) {
987 if (ktype->destroy) 990 if (ktype->destroy)
988 ktype->destroy(key); 991 ktype->destroy(key);
989 memset(&key->payload, 0xbd, sizeof(key->payload)); 992 memset(&key->payload, KEY_DESTROY, sizeof(key->payload));
990 } 993 }
991 } 994 }
992 995
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index ed71d86d2ce2..329411cf8768 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -102,7 +102,7 @@ asmlinkage long sys_add_key(const char __user *_type,
102 /* create or update the requested key and add it to the target 102 /* create or update the requested key and add it to the target
103 * keyring */ 103 * keyring */
104 key_ref = key_create_or_update(keyring_ref, type, description, 104 key_ref = key_create_or_update(keyring_ref, type, description,
105 payload, plen, 0); 105 payload, plen, KEY_ALLOC_IN_QUOTA);
106 if (!IS_ERR(key_ref)) { 106 if (!IS_ERR(key_ref)) {
107 ret = key_ref_to_ptr(key_ref)->serial; 107 ret = key_ref_to_ptr(key_ref)->serial;
108 key_ref_put(key_ref); 108 key_ref_put(key_ref);
@@ -184,7 +184,8 @@ asmlinkage long sys_request_key(const char __user *_type,
184 184
185 /* do the search */ 185 /* do the search */
186 key = request_key_and_link(ktype, description, callout_info, 186 key = request_key_and_link(ktype, description, callout_info,
187 key_ref_to_ptr(dest_ref)); 187 key_ref_to_ptr(dest_ref),
188 KEY_ALLOC_IN_QUOTA);
188 if (IS_ERR(key)) { 189 if (IS_ERR(key)) {
189 ret = PTR_ERR(key); 190 ret = PTR_ERR(key);
190 goto error5; 191 goto error5;
@@ -672,6 +673,7 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
672 */ 673 */
673long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) 674long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
674{ 675{
676 struct key_user *newowner, *zapowner = NULL;
675 struct key *key; 677 struct key *key;
676 key_ref_t key_ref; 678 key_ref_t key_ref;
677 long ret; 679 long ret;
@@ -695,19 +697,50 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
695 if (!capable(CAP_SYS_ADMIN)) { 697 if (!capable(CAP_SYS_ADMIN)) {
696 /* only the sysadmin can chown a key to some other UID */ 698 /* only the sysadmin can chown a key to some other UID */
697 if (uid != (uid_t) -1 && key->uid != uid) 699 if (uid != (uid_t) -1 && key->uid != uid)
698 goto no_access; 700 goto error_put;
699 701
700 /* only the sysadmin can set the key's GID to a group other 702 /* only the sysadmin can set the key's GID to a group other
701 * than one of those that the current process subscribes to */ 703 * than one of those that the current process subscribes to */
702 if (gid != (gid_t) -1 && gid != key->gid && !in_group_p(gid)) 704 if (gid != (gid_t) -1 && gid != key->gid && !in_group_p(gid))
703 goto no_access; 705 goto error_put;
704 } 706 }
705 707
706 /* change the UID (have to update the quotas) */ 708 /* change the UID */
707 if (uid != (uid_t) -1 && uid != key->uid) { 709 if (uid != (uid_t) -1 && uid != key->uid) {
708 /* don't support UID changing yet */ 710 ret = -ENOMEM;
709 ret = -EOPNOTSUPP; 711 newowner = key_user_lookup(uid);
710 goto no_access; 712 if (!newowner)
713 goto error_put;
714
715 /* transfer the quota burden to the new user */
716 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
717 spin_lock(&newowner->lock);
718 if (newowner->qnkeys + 1 >= KEYQUOTA_MAX_KEYS ||
719 newowner->qnbytes + key->quotalen >=
720 KEYQUOTA_MAX_BYTES)
721 goto quota_overrun;
722
723 newowner->qnkeys++;
724 newowner->qnbytes += key->quotalen;
725 spin_unlock(&newowner->lock);
726
727 spin_lock(&key->user->lock);
728 key->user->qnkeys--;
729 key->user->qnbytes -= key->quotalen;
730 spin_unlock(&key->user->lock);
731 }
732
733 atomic_dec(&key->user->nkeys);
734 atomic_inc(&newowner->nkeys);
735
736 if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
737 atomic_dec(&key->user->nikeys);
738 atomic_inc(&newowner->nikeys);
739 }
740
741 zapowner = key->user;
742 key->user = newowner;
743 key->uid = uid;
711 } 744 }
712 745
713 /* change the GID */ 746 /* change the GID */
@@ -716,12 +749,20 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
716 749
717 ret = 0; 750 ret = 0;
718 751
719 no_access: 752error_put:
720 up_write(&key->sem); 753 up_write(&key->sem);
721 key_put(key); 754 key_put(key);
722 error: 755 if (zapowner)
756 key_user_put(zapowner);
757error:
723 return ret; 758 return ret;
724 759
760quota_overrun:
761 spin_unlock(&newowner->lock);
762 zapowner = newowner;
763 ret = -EDQUOT;
764 goto error_put;
765
725} /* end keyctl_chown_key() */ 766} /* end keyctl_chown_key() */
726 767
727/*****************************************************************************/ 768/*****************************************************************************/
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 1357207fc9df..e8d02acc51e7 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -49,6 +49,7 @@ static inline unsigned keyring_hash(const char *desc)
49static int keyring_instantiate(struct key *keyring, 49static int keyring_instantiate(struct key *keyring,
50 const void *data, size_t datalen); 50 const void *data, size_t datalen);
51static int keyring_match(const struct key *keyring, const void *criterion); 51static int keyring_match(const struct key *keyring, const void *criterion);
52static void keyring_revoke(struct key *keyring);
52static void keyring_destroy(struct key *keyring); 53static void keyring_destroy(struct key *keyring);
53static void keyring_describe(const struct key *keyring, struct seq_file *m); 54static void keyring_describe(const struct key *keyring, struct seq_file *m);
54static long keyring_read(const struct key *keyring, 55static long keyring_read(const struct key *keyring,
@@ -59,6 +60,7 @@ struct key_type key_type_keyring = {
59 .def_datalen = sizeof(struct keyring_list), 60 .def_datalen = sizeof(struct keyring_list),
60 .instantiate = keyring_instantiate, 61 .instantiate = keyring_instantiate,
61 .match = keyring_match, 62 .match = keyring_match,
63 .revoke = keyring_revoke,
62 .destroy = keyring_destroy, 64 .destroy = keyring_destroy,
63 .describe = keyring_describe, 65 .describe = keyring_describe,
64 .read = keyring_read, 66 .read = keyring_read,
@@ -240,7 +242,7 @@ static long keyring_read(const struct key *keyring,
240 * allocate a keyring and link into the destination keyring 242 * allocate a keyring and link into the destination keyring
241 */ 243 */
242struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 244struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
243 struct task_struct *ctx, int not_in_quota, 245 struct task_struct *ctx, unsigned long flags,
244 struct key *dest) 246 struct key *dest)
245{ 247{
246 struct key *keyring; 248 struct key *keyring;
@@ -249,7 +251,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
249 keyring = key_alloc(&key_type_keyring, description, 251 keyring = key_alloc(&key_type_keyring, description,
250 uid, gid, ctx, 252 uid, gid, ctx,
251 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL, 253 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
252 not_in_quota); 254 flags);
253 255
254 if (!IS_ERR(keyring)) { 256 if (!IS_ERR(keyring)) {
255 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); 257 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
@@ -953,3 +955,22 @@ int keyring_clear(struct key *keyring)
953} /* end keyring_clear() */ 955} /* end keyring_clear() */
954 956
955EXPORT_SYMBOL(keyring_clear); 957EXPORT_SYMBOL(keyring_clear);
958
959/*****************************************************************************/
960/*
961 * dispose of the links from a revoked keyring
962 * - called with the key sem write-locked
963 */
964static void keyring_revoke(struct key *keyring)
965{
966 struct keyring_list *klist = keyring->payload.subscriptions;
967
968 /* adjust the quota */
969 key_payload_reserve(keyring, 0);
970
971 if (klist) {
972 rcu_assign_pointer(keyring->payload.subscriptions, NULL);
973 call_rcu(&klist->rcu, keyring_clear_rcu_disposal);
974 }
975
976} /* end keyring_revoke() */
diff --git a/security/keys/proc.c b/security/keys/proc.c
index 12b750e51fbf..686a9ee0c5de 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -137,6 +137,13 @@ static int proc_keys_show(struct seq_file *m, void *v)
137 struct timespec now; 137 struct timespec now;
138 unsigned long timo; 138 unsigned long timo;
139 char xbuf[12]; 139 char xbuf[12];
140 int rc;
141
142 /* check whether the current task is allowed to view the key (assuming
143 * non-possession) */
144 rc = key_task_permission(make_key_ref(key, 0), current, KEY_VIEW);
145 if (rc < 0)
146 return 0;
140 147
141 now = current_kernel_time(); 148 now = current_kernel_time();
142 149
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 4d9825f9962c..32150cf7c37f 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -77,7 +77,8 @@ int alloc_uid_keyring(struct user_struct *user,
77 /* concoct a default session keyring */ 77 /* concoct a default session keyring */
78 sprintf(buf, "_uid_ses.%u", user->uid); 78 sprintf(buf, "_uid_ses.%u", user->uid);
79 79
80 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0, NULL); 80 session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx,
81 KEY_ALLOC_IN_QUOTA, NULL);
81 if (IS_ERR(session_keyring)) { 82 if (IS_ERR(session_keyring)) {
82 ret = PTR_ERR(session_keyring); 83 ret = PTR_ERR(session_keyring);
83 goto error; 84 goto error;
@@ -87,8 +88,8 @@ int alloc_uid_keyring(struct user_struct *user,
87 * keyring */ 88 * keyring */
88 sprintf(buf, "_uid.%u", user->uid); 89 sprintf(buf, "_uid.%u", user->uid);
89 90
90 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0, 91 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx,
91 session_keyring); 92 KEY_ALLOC_IN_QUOTA, session_keyring);
92 if (IS_ERR(uid_keyring)) { 93 if (IS_ERR(uid_keyring)) {
93 key_put(session_keyring); 94 key_put(session_keyring);
94 ret = PTR_ERR(uid_keyring); 95 ret = PTR_ERR(uid_keyring);
@@ -144,7 +145,8 @@ int install_thread_keyring(struct task_struct *tsk)
144 145
145 sprintf(buf, "_tid.%u", tsk->pid); 146 sprintf(buf, "_tid.%u", tsk->pid);
146 147
147 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL); 148 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk,
149 KEY_ALLOC_QUOTA_OVERRUN, NULL);
148 if (IS_ERR(keyring)) { 150 if (IS_ERR(keyring)) {
149 ret = PTR_ERR(keyring); 151 ret = PTR_ERR(keyring);
150 goto error; 152 goto error;
@@ -178,7 +180,8 @@ int install_process_keyring(struct task_struct *tsk)
178 if (!tsk->signal->process_keyring) { 180 if (!tsk->signal->process_keyring) {
179 sprintf(buf, "_pid.%u", tsk->tgid); 181 sprintf(buf, "_pid.%u", tsk->tgid);
180 182
181 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL); 183 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk,
184 KEY_ALLOC_QUOTA_OVERRUN, NULL);
182 if (IS_ERR(keyring)) { 185 if (IS_ERR(keyring)) {
183 ret = PTR_ERR(keyring); 186 ret = PTR_ERR(keyring);
184 goto error; 187 goto error;
@@ -209,6 +212,7 @@ error:
209static int install_session_keyring(struct task_struct *tsk, 212static int install_session_keyring(struct task_struct *tsk,
210 struct key *keyring) 213 struct key *keyring)
211{ 214{
215 unsigned long flags;
212 struct key *old; 216 struct key *old;
213 char buf[20]; 217 char buf[20];
214 218
@@ -218,7 +222,12 @@ static int install_session_keyring(struct task_struct *tsk,
218 if (!keyring) { 222 if (!keyring) {
219 sprintf(buf, "_ses.%u", tsk->tgid); 223 sprintf(buf, "_ses.%u", tsk->tgid);
220 224
221 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL); 225 flags = KEY_ALLOC_QUOTA_OVERRUN;
226 if (tsk->signal->session_keyring)
227 flags = KEY_ALLOC_IN_QUOTA;
228
229 keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk,
230 flags, NULL);
222 if (IS_ERR(keyring)) 231 if (IS_ERR(keyring))
223 return PTR_ERR(keyring); 232 return PTR_ERR(keyring);
224 } 233 }
@@ -728,7 +737,8 @@ long join_session_keyring(const char *name)
728 keyring = find_keyring_by_name(name, 0); 737 keyring = find_keyring_by_name(name, 0);
729 if (PTR_ERR(keyring) == -ENOKEY) { 738 if (PTR_ERR(keyring) == -ENOKEY) {
730 /* not found - try and create a new one */ 739 /* not found - try and create a new one */
731 keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk, 0, NULL); 740 keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk,
741 KEY_ALLOC_IN_QUOTA, NULL);
732 if (IS_ERR(keyring)) { 742 if (IS_ERR(keyring)) {
733 ret = PTR_ERR(keyring); 743 ret = PTR_ERR(keyring);
734 goto error2; 744 goto error2;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index eab66a06ca53..58d1efd4fc2c 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -48,8 +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, 51 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, current,
52 current, 1, NULL); 52 KEY_ALLOC_QUOTA_OVERRUN, NULL);
53 if (IS_ERR(keyring)) { 53 if (IS_ERR(keyring)) {
54 ret = PTR_ERR(keyring); 54 ret = PTR_ERR(keyring);
55 goto error_alloc; 55 goto error_alloc;
@@ -126,7 +126,8 @@ error_alloc:
126 */ 126 */
127static struct key *__request_key_construction(struct key_type *type, 127static struct key *__request_key_construction(struct key_type *type,
128 const char *description, 128 const char *description,
129 const char *callout_info) 129 const char *callout_info,
130 unsigned long flags)
130{ 131{
131 request_key_actor_t actor; 132 request_key_actor_t actor;
132 struct key_construction cons; 133 struct key_construction cons;
@@ -134,12 +135,12 @@ static struct key *__request_key_construction(struct key_type *type,
134 struct key *key, *authkey; 135 struct key *key, *authkey;
135 int ret, negated; 136 int ret, negated;
136 137
137 kenter("%s,%s,%s", type->name, description, callout_info); 138 kenter("%s,%s,%s,%lx", type->name, description, callout_info, flags);
138 139
139 /* create a key and add it to the queue */ 140 /* create a key and add it to the queue */
140 key = key_alloc(type, description, 141 key = key_alloc(type, description,
141 current->fsuid, current->fsgid, 142 current->fsuid, current->fsgid, current, KEY_POS_ALL,
142 current, KEY_POS_ALL, 0); 143 flags);
143 if (IS_ERR(key)) 144 if (IS_ERR(key))
144 goto alloc_failed; 145 goto alloc_failed;
145 146
@@ -258,15 +259,16 @@ alloc_failed:
258static struct key *request_key_construction(struct key_type *type, 259static struct key *request_key_construction(struct key_type *type,
259 const char *description, 260 const char *description,
260 struct key_user *user, 261 struct key_user *user,
261 const char *callout_info) 262 const char *callout_info,
263 unsigned long flags)
262{ 264{
263 struct key_construction *pcons; 265 struct key_construction *pcons;
264 struct key *key, *ckey; 266 struct key *key, *ckey;
265 267
266 DECLARE_WAITQUEUE(myself, current); 268 DECLARE_WAITQUEUE(myself, current);
267 269
268 kenter("%s,%s,{%d},%s", 270 kenter("%s,%s,{%d},%s,%lx",
269 type->name, description, user->uid, callout_info); 271 type->name, description, user->uid, callout_info, flags);
270 272
271 /* see if there's such a key under construction already */ 273 /* see if there's such a key under construction already */
272 down_write(&key_construction_sem); 274 down_write(&key_construction_sem);
@@ -282,7 +284,8 @@ static struct key *request_key_construction(struct key_type *type,
282 } 284 }
283 285
284 /* see about getting userspace to construct the key */ 286 /* see about getting userspace to construct the key */
285 key = __request_key_construction(type, description, callout_info); 287 key = __request_key_construction(type, description, callout_info,
288 flags);
286 error: 289 error:
287 kleave(" = %p", key); 290 kleave(" = %p", key);
288 return key; 291 return key;
@@ -389,14 +392,15 @@ static void request_key_link(struct key *key, struct key *dest_keyring)
389struct key *request_key_and_link(struct key_type *type, 392struct key *request_key_and_link(struct key_type *type,
390 const char *description, 393 const char *description,
391 const char *callout_info, 394 const char *callout_info,
392 struct key *dest_keyring) 395 struct key *dest_keyring,
396 unsigned long flags)
393{ 397{
394 struct key_user *user; 398 struct key_user *user;
395 struct key *key; 399 struct key *key;
396 key_ref_t key_ref; 400 key_ref_t key_ref;
397 401
398 kenter("%s,%s,%s,%p", 402 kenter("%s,%s,%s,%p,%lx",
399 type->name, description, callout_info, dest_keyring); 403 type->name, description, callout_info, dest_keyring, flags);
400 404
401 /* search all the process keyrings for a key */ 405 /* search all the process keyrings for a key */
402 key_ref = search_process_keyrings(type, description, type->match, 406 key_ref = search_process_keyrings(type, description, type->match,
@@ -429,7 +433,8 @@ struct key *request_key_and_link(struct key_type *type,
429 /* ask userspace (returns NULL if it waited on a key 433 /* ask userspace (returns NULL if it waited on a key
430 * being constructed) */ 434 * being constructed) */
431 key = request_key_construction(type, description, 435 key = request_key_construction(type, description,
432 user, callout_info); 436 user, callout_info,
437 flags);
433 if (key) 438 if (key)
434 break; 439 break;
435 440
@@ -485,7 +490,8 @@ struct key *request_key(struct key_type *type,
485 const char *description, 490 const char *description,
486 const char *callout_info) 491 const char *callout_info)
487{ 492{
488 return request_key_and_link(type, description, callout_info, NULL); 493 return request_key_and_link(type, description, callout_info, NULL,
494 KEY_ALLOC_IN_QUOTA);
489 495
490} /* end request_key() */ 496} /* end request_key() */
491 497
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index cb9817ced3fd..cbf58a91b00a 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -187,7 +187,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
187 authkey = key_alloc(&key_type_request_key_auth, desc, 187 authkey = key_alloc(&key_type_request_key_auth, desc,
188 current->fsuid, current->fsgid, current, 188 current->fsuid, current->fsgid, current,
189 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | 189 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
190 KEY_USR_VIEW, 1); 190 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA);
191 if (IS_ERR(authkey)) { 191 if (IS_ERR(authkey)) {
192 ret = PTR_ERR(authkey); 192 ret = PTR_ERR(authkey);
193 goto error_alloc; 193 goto error_alloc;
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 8e71895b97a7..5bbfdebb7acf 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -28,6 +28,7 @@ struct key_type key_type_user = {
28 .instantiate = user_instantiate, 28 .instantiate = user_instantiate,
29 .update = user_update, 29 .update = user_update,
30 .match = user_match, 30 .match = user_match,
31 .revoke = user_revoke,
31 .destroy = user_destroy, 32 .destroy = user_destroy,
32 .describe = user_describe, 33 .describe = user_describe,
33 .read = user_read, 34 .read = user_read,
@@ -67,6 +68,7 @@ error:
67 return ret; 68 return ret;
68 69
69} /* end user_instantiate() */ 70} /* end user_instantiate() */
71
70EXPORT_SYMBOL_GPL(user_instantiate); 72EXPORT_SYMBOL_GPL(user_instantiate);
71 73
72/*****************************************************************************/ 74/*****************************************************************************/
@@ -141,7 +143,28 @@ EXPORT_SYMBOL_GPL(user_match);
141 143
142/*****************************************************************************/ 144/*****************************************************************************/
143/* 145/*
144 * dispose of the data dangling from the corpse of a user 146 * dispose of the links from a revoked keyring
147 * - called with the key sem write-locked
148 */
149void user_revoke(struct key *key)
150{
151 struct user_key_payload *upayload = key->payload.data;
152
153 /* clear the quota */
154 key_payload_reserve(key, 0);
155
156 if (upayload) {
157 rcu_assign_pointer(key->payload.data, NULL);
158 call_rcu(&upayload->rcu, user_update_rcu_disposal);
159 }
160
161} /* end user_revoke() */
162
163EXPORT_SYMBOL(user_revoke);
164
165/*****************************************************************************/
166/*
167 * dispose of the data dangling from the corpse of a user key
145 */ 168 */
146void user_destroy(struct key *key) 169void user_destroy(struct key *key)
147{ 170{