Blame view
security/keys/user_defined.c
3.93 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" |
1da177e4c Linux-2.6.12-rc2 |
20 21 22 23 24 25 26 |
/* * 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 = { .name = "user", .instantiate = user_instantiate, |
1da177e4c Linux-2.6.12-rc2 |
27 28 |
.update = user_update, .match = user_match, |
31204ed92 [PATCH] keys: dis... |
29 |
.revoke = user_revoke, |
1da177e4c Linux-2.6.12-rc2 |
30 31 32 33 |
.destroy = user_destroy, .describe = user_describe, .read = user_read, }; |
16c29b67f [PATCH] eCryptfs:... |
34 |
EXPORT_SYMBOL_GPL(key_type_user); |
1da177e4c Linux-2.6.12-rc2 |
35 36 37 |
/* * instantiate a user defined key */ |
2aa349f6e [PATCH] Keys: Exp... |
38 |
int user_instantiate(struct key *key, const void *data, size_t datalen) |
1da177e4c Linux-2.6.12-rc2 |
39 |
{ |
76d8aeabf [PATCH] keys: Dis... |
40 |
struct user_key_payload *upayload; |
1da177e4c Linux-2.6.12-rc2 |
41 42 43 44 45 46 47 48 49 |
int ret; ret = -EINVAL; if (datalen <= 0 || datalen > 32767 || !data) goto error; ret = key_payload_reserve(key, datalen); if (ret < 0) goto error; |
1da177e4c Linux-2.6.12-rc2 |
50 |
ret = -ENOMEM; |
76d8aeabf [PATCH] keys: Dis... |
51 52 |
upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL); if (!upayload) |
1da177e4c Linux-2.6.12-rc2 |
53 |
goto error; |
76d8aeabf [PATCH] keys: Dis... |
54 55 56 57 |
/* attach the data */ upayload->datalen = datalen; memcpy(upayload->data, data, datalen); rcu_assign_pointer(key->payload.data, upayload); |
1da177e4c Linux-2.6.12-rc2 |
58 |
ret = 0; |
2aa349f6e [PATCH] Keys: Exp... |
59 |
error: |
1da177e4c Linux-2.6.12-rc2 |
60 |
return ret; |
a8b17ed01 KEYS: Do some sty... |
61 |
} |
31204ed92 [PATCH] keys: dis... |
62 |
|
2aa349f6e [PATCH] Keys: Exp... |
63 |
EXPORT_SYMBOL_GPL(user_instantiate); |
1da177e4c Linux-2.6.12-rc2 |
64 |
/* |
1da177e4c Linux-2.6.12-rc2 |
65 |
* update a user defined key |
76d8aeabf [PATCH] keys: Dis... |
66 |
* - the key's semaphore is write-locked |
1da177e4c Linux-2.6.12-rc2 |
67 |
*/ |
2aa349f6e [PATCH] Keys: Exp... |
68 |
int user_update(struct key *key, const void *data, size_t datalen) |
1da177e4c Linux-2.6.12-rc2 |
69 |
{ |
76d8aeabf [PATCH] keys: Dis... |
70 |
struct user_key_payload *upayload, *zap; |
1da177e4c Linux-2.6.12-rc2 |
71 72 73 74 75 |
int ret; ret = -EINVAL; if (datalen <= 0 || datalen > 32767 || !data) goto error; |
76d8aeabf [PATCH] keys: Dis... |
76 |
/* construct a replacement payload */ |
1da177e4c Linux-2.6.12-rc2 |
77 |
ret = -ENOMEM; |
76d8aeabf [PATCH] keys: Dis... |
78 79 |
upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL); if (!upayload) |
1da177e4c Linux-2.6.12-rc2 |
80 |
goto error; |
76d8aeabf [PATCH] keys: Dis... |
81 82 |
upayload->datalen = datalen; memcpy(upayload->data, data, datalen); |
1da177e4c Linux-2.6.12-rc2 |
83 84 |
/* check the quota and attach the new data */ |
76d8aeabf [PATCH] keys: Dis... |
85 |
zap = upayload; |
1da177e4c Linux-2.6.12-rc2 |
86 87 88 89 90 91 |
ret = key_payload_reserve(key, datalen); if (ret == 0) { /* attach the new data, displacing the old */ zap = key->payload.data; |
76d8aeabf [PATCH] keys: Dis... |
92 |
rcu_assign_pointer(key->payload.data, upayload); |
1da177e4c Linux-2.6.12-rc2 |
93 94 |
key->expiry = 0; } |
9f35a33b8 KEYS: Fix a NULL ... |
95 96 |
if (zap) kfree_rcu(zap, rcu); |
1da177e4c Linux-2.6.12-rc2 |
97 |
|
2aa349f6e [PATCH] Keys: Exp... |
98 |
error: |
1da177e4c Linux-2.6.12-rc2 |
99 |
return ret; |
a8b17ed01 KEYS: Do some sty... |
100 |
} |
1da177e4c Linux-2.6.12-rc2 |
101 |
|
2aa349f6e [PATCH] Keys: Exp... |
102 |
EXPORT_SYMBOL_GPL(user_update); |
1da177e4c Linux-2.6.12-rc2 |
103 104 105 |
/* * match users on their name */ |
2aa349f6e [PATCH] Keys: Exp... |
106 |
int user_match(const struct key *key, const void *description) |
1da177e4c Linux-2.6.12-rc2 |
107 108 |
{ return strcmp(key->description, description) == 0; |
a8b17ed01 KEYS: Do some sty... |
109 |
} |
1da177e4c Linux-2.6.12-rc2 |
110 |
|
2aa349f6e [PATCH] Keys: Exp... |
111 |
EXPORT_SYMBOL_GPL(user_match); |
1da177e4c Linux-2.6.12-rc2 |
112 |
/* |
31204ed92 [PATCH] keys: dis... |
113 114 115 116 117 118 119 120 121 122 123 124 |
* 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) { rcu_assign_pointer(key->payload.data, NULL); |
3acb458c3 security,rcu: con... |
125 |
kfree_rcu(upayload, rcu); |
31204ed92 [PATCH] keys: dis... |
126 |
} |
a8b17ed01 KEYS: Do some sty... |
127 |
} |
31204ed92 [PATCH] keys: dis... |
128 129 |
EXPORT_SYMBOL(user_revoke); |
31204ed92 [PATCH] keys: dis... |
130 131 |
/* * dispose of the data dangling from the corpse of a user key |
1da177e4c Linux-2.6.12-rc2 |
132 |
*/ |
2aa349f6e [PATCH] Keys: Exp... |
133 |
void user_destroy(struct key *key) |
1da177e4c Linux-2.6.12-rc2 |
134 |
{ |
76d8aeabf [PATCH] keys: Dis... |
135 136 137 |
struct user_key_payload *upayload = key->payload.data; kfree(upayload); |
a8b17ed01 KEYS: Do some sty... |
138 |
} |
1da177e4c Linux-2.6.12-rc2 |
139 |
|
2aa349f6e [PATCH] Keys: Exp... |
140 |
EXPORT_SYMBOL_GPL(user_destroy); |
1da177e4c Linux-2.6.12-rc2 |
141 |
/* |
76d8aeabf [PATCH] keys: Dis... |
142 |
* describe the user key |
1da177e4c Linux-2.6.12-rc2 |
143 |
*/ |
2aa349f6e [PATCH] Keys: Exp... |
144 |
void user_describe(const struct key *key, struct seq_file *m) |
1da177e4c Linux-2.6.12-rc2 |
145 146 |
{ seq_puts(m, key->description); |
78b7280cc KEYS: Improve /pr... |
147 148 |
if (key_is_instantiated(key)) seq_printf(m, ": %u", key->datalen); |
a8b17ed01 KEYS: Do some sty... |
149 |
} |
1da177e4c Linux-2.6.12-rc2 |
150 |
|
2aa349f6e [PATCH] Keys: Exp... |
151 |
EXPORT_SYMBOL_GPL(user_describe); |
1da177e4c Linux-2.6.12-rc2 |
152 153 |
/* * read the key data |
76d8aeabf [PATCH] keys: Dis... |
154 |
* - the key's semaphore is read-locked |
1da177e4c Linux-2.6.12-rc2 |
155 |
*/ |
2aa349f6e [PATCH] Keys: Exp... |
156 |
long user_read(const struct key *key, char __user *buffer, size_t buflen) |
1da177e4c Linux-2.6.12-rc2 |
157 |
{ |
76d8aeabf [PATCH] keys: Dis... |
158 159 |
struct user_key_payload *upayload; long ret; |
633e804e8 KEYS: Add an RCU ... |
160 |
upayload = rcu_dereference_key(key); |
76d8aeabf [PATCH] keys: Dis... |
161 |
ret = upayload->datalen; |
1da177e4c Linux-2.6.12-rc2 |
162 163 164 |
/* we can return the data as is */ if (buffer && buflen > 0) { |
76d8aeabf [PATCH] keys: Dis... |
165 166 |
if (buflen > upayload->datalen) buflen = upayload->datalen; |
1da177e4c Linux-2.6.12-rc2 |
167 |
|
76d8aeabf [PATCH] keys: Dis... |
168 |
if (copy_to_user(buffer, upayload->data, buflen) != 0) |
1da177e4c Linux-2.6.12-rc2 |
169 170 171 172 |
ret = -EFAULT; } return ret; |
a8b17ed01 KEYS: Do some sty... |
173 |
} |
2aa349f6e [PATCH] Keys: Exp... |
174 175 |
EXPORT_SYMBOL_GPL(user_read); |