aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/key.c
diff options
context:
space:
mode:
authorSerge E. Hallyn <serue@us.ibm.com>2009-02-26 19:27:38 -0500
committerJames Morris <jmorris@namei.org>2009-02-26 20:35:06 -0500
commit1d1e97562e5e2ac60fb7b25437ba619f95f67fab (patch)
tree68a9c52ecbff0782dd9b9438685afc3b40b6f707 /security/keys/key.c
parentbe38e0fd5f90a91d09e0a85ffb294b70a7be6259 (diff)
keys: distinguish per-uid keys in different namespaces
per-uid keys were looked by uid only. Use the user namespace to distinguish the same uid in different namespaces. This does not address key_permission. So a task can for instance try to join a keyring owned by the same uid in another namespace. That will be handled by a separate patch. Signed-off-by: Serge E. Hallyn <serue@us.ibm.com> Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/keys/key.c')
-rw-r--r--security/keys/key.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/security/keys/key.c b/security/keys/key.c
index f76c8a546fd3..4a1297d1ada4 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -18,6 +18,7 @@
18#include <linux/workqueue.h> 18#include <linux/workqueue.h>
19#include <linux/random.h> 19#include <linux/random.h>
20#include <linux/err.h> 20#include <linux/err.h>
21#include <linux/user_namespace.h>
21#include "internal.h" 22#include "internal.h"
22 23
23static struct kmem_cache *key_jar; 24static struct kmem_cache *key_jar;
@@ -60,7 +61,7 @@ void __key_check(const struct key *key)
60 * get the key quota record for a user, allocating a new record if one doesn't 61 * get the key quota record for a user, allocating a new record if one doesn't
61 * already exist 62 * already exist
62 */ 63 */
63struct key_user *key_user_lookup(uid_t uid) 64struct key_user *key_user_lookup(uid_t uid, struct user_namespace *user_ns)
64{ 65{
65 struct key_user *candidate = NULL, *user; 66 struct key_user *candidate = NULL, *user;
66 struct rb_node *parent = NULL; 67 struct rb_node *parent = NULL;
@@ -79,6 +80,10 @@ struct key_user *key_user_lookup(uid_t uid)
79 p = &(*p)->rb_left; 80 p = &(*p)->rb_left;
80 else if (uid > user->uid) 81 else if (uid > user->uid)
81 p = &(*p)->rb_right; 82 p = &(*p)->rb_right;
83 else if (user_ns < user->user_ns)
84 p = &(*p)->rb_left;
85 else if (user_ns > user->user_ns)
86 p = &(*p)->rb_right;
82 else 87 else
83 goto found; 88 goto found;
84 } 89 }
@@ -106,6 +111,7 @@ struct key_user *key_user_lookup(uid_t uid)
106 atomic_set(&candidate->nkeys, 0); 111 atomic_set(&candidate->nkeys, 0);
107 atomic_set(&candidate->nikeys, 0); 112 atomic_set(&candidate->nikeys, 0);
108 candidate->uid = uid; 113 candidate->uid = uid;
114 candidate->user_ns = get_user_ns(user_ns);
109 candidate->qnkeys = 0; 115 candidate->qnkeys = 0;
110 candidate->qnbytes = 0; 116 candidate->qnbytes = 0;
111 spin_lock_init(&candidate->lock); 117 spin_lock_init(&candidate->lock);
@@ -136,6 +142,7 @@ void key_user_put(struct key_user *user)
136 if (atomic_dec_and_lock(&user->usage, &key_user_lock)) { 142 if (atomic_dec_and_lock(&user->usage, &key_user_lock)) {
137 rb_erase(&user->node, &key_user_tree); 143 rb_erase(&user->node, &key_user_tree);
138 spin_unlock(&key_user_lock); 144 spin_unlock(&key_user_lock);
145 put_user_ns(user->user_ns);
139 146
140 kfree(user); 147 kfree(user);
141 } 148 }
@@ -234,7 +241,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
234 quotalen = desclen + type->def_datalen; 241 quotalen = desclen + type->def_datalen;
235 242
236 /* get hold of the key tracking for this user */ 243 /* get hold of the key tracking for this user */
237 user = key_user_lookup(uid); 244 user = key_user_lookup(uid, cred->user->user_ns);
238 if (!user) 245 if (!user)
239 goto no_memory_1; 246 goto no_memory_1;
240 247