Blame view
security/keys/user_defined.c
4.98 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* user_defined.c: user defined key type * * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include <linux/module.h> #include <linux/init.h> |
1da177e4c Linux-2.6.12-rc2 |
14 15 16 |
#include <linux/slab.h> #include <linux/seq_file.h> #include <linux/err.h> |
2aa349f6e [PATCH] Keys: Exp... |
17 |
#include <keys/user-type.h> |
1da177e4c Linux-2.6.12-rc2 |
18 19 |
#include <asm/uaccess.h> #include "internal.h" |
9f6ed2ca2 keys: add a "logo... |
20 |
static int logon_vet_description(const char *desc); |
1da177e4c Linux-2.6.12-rc2 |
21 22 23 24 25 |
/* * user defined keys take an arbitrary string as the description and an * arbitrary blob of data as the payload */ struct key_type key_type_user = { |
4bdf0bc30 KEYS: Introduce a... |
26 27 28 29 30 31 32 33 34 |
.name = "user", .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, .instantiate = user_instantiate, .update = user_update, .match = user_match, .revoke = user_revoke, .destroy = user_destroy, .describe = user_describe, .read = user_read, |
1da177e4c Linux-2.6.12-rc2 |
35 |
}; |
16c29b67f [PATCH] eCryptfs:... |
36 |
EXPORT_SYMBOL_GPL(key_type_user); |
1da177e4c Linux-2.6.12-rc2 |
37 |
/* |
9f6ed2ca2 keys: add a "logo... |
38 39 40 41 42 43 44 |
* This key type is essentially the same as key_type_user, but it does * not define a .read op. This is suitable for storing username and * password pairs in the keyring that you do not want to be readable * from userspace. */ struct key_type key_type_logon = { .name = "logon", |
4bdf0bc30 KEYS: Introduce a... |
45 |
.def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, |
9f6ed2ca2 keys: add a "logo... |
46 47 48 49 50 51 52 53 54 55 56 |
.instantiate = user_instantiate, .update = user_update, .match = user_match, .revoke = user_revoke, .destroy = user_destroy, .describe = user_describe, .vet_description = logon_vet_description, }; EXPORT_SYMBOL_GPL(key_type_logon); /* |
1da177e4c Linux-2.6.12-rc2 |
57 58 |
* instantiate a user defined key */ |
cf7f601c0 KEYS: Add payload... |
59 |
int user_instantiate(struct key *key, struct key_preparsed_payload *prep) |
1da177e4c Linux-2.6.12-rc2 |
60 |
{ |
76d8aeabf [PATCH] keys: Dis... |
61 |
struct user_key_payload *upayload; |
cf7f601c0 KEYS: Add payload... |
62 |
size_t datalen = prep->datalen; |
1da177e4c Linux-2.6.12-rc2 |
63 64 65 |
int ret; ret = -EINVAL; |
cf7f601c0 KEYS: Add payload... |
66 |
if (datalen <= 0 || datalen > 32767 || !prep->data) |
1da177e4c Linux-2.6.12-rc2 |
67 68 69 70 71 |
goto error; ret = key_payload_reserve(key, datalen); if (ret < 0) goto error; |
1da177e4c Linux-2.6.12-rc2 |
72 |
ret = -ENOMEM; |
76d8aeabf [PATCH] keys: Dis... |
73 74 |
upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL); if (!upayload) |
1da177e4c Linux-2.6.12-rc2 |
75 |
goto error; |
76d8aeabf [PATCH] keys: Dis... |
76 77 |
/* attach the data */ upayload->datalen = datalen; |
cf7f601c0 KEYS: Add payload... |
78 |
memcpy(upayload->data, prep->data, datalen); |
f6b24579d keys: fix user_de... |
79 |
rcu_assign_keypointer(key, upayload); |
1da177e4c Linux-2.6.12-rc2 |
80 |
ret = 0; |
2aa349f6e [PATCH] Keys: Exp... |
81 |
error: |
1da177e4c Linux-2.6.12-rc2 |
82 |
return ret; |
a8b17ed01 KEYS: Do some sty... |
83 |
} |
31204ed92 [PATCH] keys: dis... |
84 |
|
2aa349f6e [PATCH] Keys: Exp... |
85 |
EXPORT_SYMBOL_GPL(user_instantiate); |
1da177e4c Linux-2.6.12-rc2 |
86 |
/* |
1da177e4c Linux-2.6.12-rc2 |
87 |
* update a user defined key |
76d8aeabf [PATCH] keys: Dis... |
88 |
* - the key's semaphore is write-locked |
1da177e4c Linux-2.6.12-rc2 |
89 |
*/ |
cf7f601c0 KEYS: Add payload... |
90 |
int user_update(struct key *key, struct key_preparsed_payload *prep) |
1da177e4c Linux-2.6.12-rc2 |
91 |
{ |
76d8aeabf [PATCH] keys: Dis... |
92 |
struct user_key_payload *upayload, *zap; |
cf7f601c0 KEYS: Add payload... |
93 |
size_t datalen = prep->datalen; |
1da177e4c Linux-2.6.12-rc2 |
94 95 96 |
int ret; ret = -EINVAL; |
cf7f601c0 KEYS: Add payload... |
97 |
if (datalen <= 0 || datalen > 32767 || !prep->data) |
1da177e4c Linux-2.6.12-rc2 |
98 |
goto error; |
76d8aeabf [PATCH] keys: Dis... |
99 |
/* construct a replacement payload */ |
1da177e4c Linux-2.6.12-rc2 |
100 |
ret = -ENOMEM; |
76d8aeabf [PATCH] keys: Dis... |
101 102 |
upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL); if (!upayload) |
1da177e4c Linux-2.6.12-rc2 |
103 |
goto error; |
76d8aeabf [PATCH] keys: Dis... |
104 |
upayload->datalen = datalen; |
cf7f601c0 KEYS: Add payload... |
105 |
memcpy(upayload->data, prep->data, datalen); |
1da177e4c Linux-2.6.12-rc2 |
106 107 |
/* check the quota and attach the new data */ |
76d8aeabf [PATCH] keys: Dis... |
108 |
zap = upayload; |
1da177e4c Linux-2.6.12-rc2 |
109 110 111 112 113 114 |
ret = key_payload_reserve(key, datalen); if (ret == 0) { /* attach the new data, displacing the old */ zap = key->payload.data; |
f6b24579d keys: fix user_de... |
115 |
rcu_assign_keypointer(key, upayload); |
1da177e4c Linux-2.6.12-rc2 |
116 117 |
key->expiry = 0; } |
9f35a33b8 KEYS: Fix a NULL ... |
118 119 |
if (zap) kfree_rcu(zap, rcu); |
1da177e4c Linux-2.6.12-rc2 |
120 |
|
2aa349f6e [PATCH] Keys: Exp... |
121 |
error: |
1da177e4c Linux-2.6.12-rc2 |
122 |
return ret; |
a8b17ed01 KEYS: Do some sty... |
123 |
} |
1da177e4c Linux-2.6.12-rc2 |
124 |
|
2aa349f6e [PATCH] Keys: Exp... |
125 |
EXPORT_SYMBOL_GPL(user_update); |
1da177e4c Linux-2.6.12-rc2 |
126 127 128 |
/* * match users on their name */ |
2aa349f6e [PATCH] Keys: Exp... |
129 |
int user_match(const struct key *key, const void *description) |
1da177e4c Linux-2.6.12-rc2 |
130 131 |
{ return strcmp(key->description, description) == 0; |
a8b17ed01 KEYS: Do some sty... |
132 |
} |
1da177e4c Linux-2.6.12-rc2 |
133 |
|
2aa349f6e [PATCH] Keys: Exp... |
134 |
EXPORT_SYMBOL_GPL(user_match); |
1da177e4c Linux-2.6.12-rc2 |
135 |
/* |
31204ed92 [PATCH] keys: dis... |
136 137 138 139 140 141 142 143 144 145 146 |
* dispose of the links from a revoked keyring * - called with the key sem write-locked */ void user_revoke(struct key *key) { struct user_key_payload *upayload = key->payload.data; /* clear the quota */ key_payload_reserve(key, 0); if (upayload) { |
f6b24579d keys: fix user_de... |
147 |
rcu_assign_keypointer(key, NULL); |
3acb458c3 security,rcu: con... |
148 |
kfree_rcu(upayload, rcu); |
31204ed92 [PATCH] keys: dis... |
149 |
} |
a8b17ed01 KEYS: Do some sty... |
150 |
} |
31204ed92 [PATCH] keys: dis... |
151 152 |
EXPORT_SYMBOL(user_revoke); |
31204ed92 [PATCH] keys: dis... |
153 154 |
/* * dispose of the data dangling from the corpse of a user key |
1da177e4c Linux-2.6.12-rc2 |
155 |
*/ |
2aa349f6e [PATCH] Keys: Exp... |
156 |
void user_destroy(struct key *key) |
1da177e4c Linux-2.6.12-rc2 |
157 |
{ |
76d8aeabf [PATCH] keys: Dis... |
158 159 160 |
struct user_key_payload *upayload = key->payload.data; kfree(upayload); |
a8b17ed01 KEYS: Do some sty... |
161 |
} |
1da177e4c Linux-2.6.12-rc2 |
162 |
|
2aa349f6e [PATCH] Keys: Exp... |
163 |
EXPORT_SYMBOL_GPL(user_destroy); |
1da177e4c Linux-2.6.12-rc2 |
164 |
/* |
76d8aeabf [PATCH] keys: Dis... |
165 |
* describe the user key |
1da177e4c Linux-2.6.12-rc2 |
166 |
*/ |
2aa349f6e [PATCH] Keys: Exp... |
167 |
void user_describe(const struct key *key, struct seq_file *m) |
1da177e4c Linux-2.6.12-rc2 |
168 169 |
{ seq_puts(m, key->description); |
78b7280cc KEYS: Improve /pr... |
170 171 |
if (key_is_instantiated(key)) seq_printf(m, ": %u", key->datalen); |
a8b17ed01 KEYS: Do some sty... |
172 |
} |
1da177e4c Linux-2.6.12-rc2 |
173 |
|
2aa349f6e [PATCH] Keys: Exp... |
174 |
EXPORT_SYMBOL_GPL(user_describe); |
1da177e4c Linux-2.6.12-rc2 |
175 176 |
/* * read the key data |
76d8aeabf [PATCH] keys: Dis... |
177 |
* - the key's semaphore is read-locked |
1da177e4c Linux-2.6.12-rc2 |
178 |
*/ |
2aa349f6e [PATCH] Keys: Exp... |
179 |
long user_read(const struct key *key, char __user *buffer, size_t buflen) |
1da177e4c Linux-2.6.12-rc2 |
180 |
{ |
76d8aeabf [PATCH] keys: Dis... |
181 182 |
struct user_key_payload *upayload; long ret; |
633e804e8 KEYS: Add an RCU ... |
183 |
upayload = rcu_dereference_key(key); |
76d8aeabf [PATCH] keys: Dis... |
184 |
ret = upayload->datalen; |
1da177e4c Linux-2.6.12-rc2 |
185 186 187 |
/* we can return the data as is */ if (buffer && buflen > 0) { |
76d8aeabf [PATCH] keys: Dis... |
188 189 |
if (buflen > upayload->datalen) buflen = upayload->datalen; |
1da177e4c Linux-2.6.12-rc2 |
190 |
|
76d8aeabf [PATCH] keys: Dis... |
191 |
if (copy_to_user(buffer, upayload->data, buflen) != 0) |
1da177e4c Linux-2.6.12-rc2 |
192 193 194 195 |
ret = -EFAULT; } return ret; |
a8b17ed01 KEYS: Do some sty... |
196 |
} |
2aa349f6e [PATCH] Keys: Exp... |
197 198 |
EXPORT_SYMBOL_GPL(user_read); |
9f6ed2ca2 keys: add a "logo... |
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
/* Vet the description for a "logon" key */ static int logon_vet_description(const char *desc) { char *p; /* require a "qualified" description string */ p = strchr(desc, ':'); if (!p) return -EINVAL; /* also reject description with ':' as first char */ if (p == desc) return -EINVAL; return 0; } |