aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/keys/user-type.h47
-rw-r--r--security/keys/user_defined.c49
2 files changed, 71 insertions, 25 deletions
diff --git a/include/keys/user-type.h b/include/keys/user-type.h
new file mode 100644
index 000000000000..26f6ec38577a
--- /dev/null
+++ b/include/keys/user-type.h
@@ -0,0 +1,47 @@
1/* user-type.h: User-defined key type
2 *
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#ifndef _KEYS_USER_TYPE_H
13#define _KEYS_USER_TYPE_H
14
15#include <linux/key.h>
16#include <linux/rcupdate.h>
17
18/*****************************************************************************/
19/*
20 * the payload for a key of type "user"
21 * - once filled in and attached to a key:
22 * - the payload struct is invariant may not be changed, only replaced
23 * - the payload must be read with RCU procedures or with the key semaphore
24 * held
25 * - the payload may only be replaced with the key semaphore write-locked
26 * - the key's data length is the size of the actual data, not including the
27 * payload wrapper
28 */
29struct user_key_payload {
30 struct rcu_head rcu; /* RCU destructor */
31 unsigned short datalen; /* length of this data */
32 char data[0]; /* actual data */
33};
34
35extern struct key_type key_type_user;
36
37extern int user_instantiate(struct key *key, const void *data, size_t datalen);
38extern int user_duplicate(struct key *key, const struct key *source);
39extern int user_update(struct key *key, const void *data, size_t datalen);
40extern int user_match(const struct key *key, const void *criterion);
41extern void user_destroy(struct key *key);
42extern void user_describe(const struct key *user, struct seq_file *m);
43extern long user_read(const struct key *key,
44 char __user *buffer, size_t buflen);
45
46
47#endif /* _KEYS_USER_TYPE_H */
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index e446acba73d3..cbda3b2780a1 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -15,18 +15,10 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/seq_file.h> 16#include <linux/seq_file.h>
17#include <linux/err.h> 17#include <linux/err.h>
18#include <keys/user-type.h>
18#include <asm/uaccess.h> 19#include <asm/uaccess.h>
19#include "internal.h" 20#include "internal.h"
20 21
21static int user_instantiate(struct key *key, const void *data, size_t datalen);
22static int user_duplicate(struct key *key, const struct key *source);
23static int user_update(struct key *key, const void *data, size_t datalen);
24static int user_match(const struct key *key, const void *criterion);
25static void user_destroy(struct key *key);
26static void user_describe(const struct key *user, struct seq_file *m);
27static long user_read(const struct key *key,
28 char __user *buffer, size_t buflen);
29
30/* 22/*
31 * user defined keys take an arbitrary string as the description and an 23 * user defined keys take an arbitrary string as the description and an
32 * arbitrary blob of data as the payload 24 * arbitrary blob of data as the payload
@@ -42,19 +34,13 @@ struct key_type key_type_user = {
42 .read = user_read, 34 .read = user_read,
43}; 35};
44 36
45struct user_key_payload {
46 struct rcu_head rcu; /* RCU destructor */
47 unsigned short datalen; /* length of this data */
48 char data[0]; /* actual data */
49};
50
51EXPORT_SYMBOL_GPL(key_type_user); 37EXPORT_SYMBOL_GPL(key_type_user);
52 38
53/*****************************************************************************/ 39/*****************************************************************************/
54/* 40/*
55 * instantiate a user defined key 41 * instantiate a user defined key
56 */ 42 */
57static int user_instantiate(struct key *key, const void *data, size_t datalen) 43int user_instantiate(struct key *key, const void *data, size_t datalen)
58{ 44{
59 struct user_key_payload *upayload; 45 struct user_key_payload *upayload;
60 int ret; 46 int ret;
@@ -78,18 +64,20 @@ static int user_instantiate(struct key *key, const void *data, size_t datalen)
78 rcu_assign_pointer(key->payload.data, upayload); 64 rcu_assign_pointer(key->payload.data, upayload);
79 ret = 0; 65 ret = 0;
80 66
81 error: 67error:
82 return ret; 68 return ret;
83 69
84} /* end user_instantiate() */ 70} /* end user_instantiate() */
85 71
72EXPORT_SYMBOL_GPL(user_instantiate);
73
86/*****************************************************************************/ 74/*****************************************************************************/
87/* 75/*
88 * duplicate a user defined key 76 * duplicate a user defined key
89 * - both keys' semaphores are locked against further modification 77 * - both keys' semaphores are locked against further modification
90 * - the new key cannot yet be accessed 78 * - the new key cannot yet be accessed
91 */ 79 */
92static int user_duplicate(struct key *key, const struct key *source) 80int user_duplicate(struct key *key, const struct key *source)
93{ 81{
94 struct user_key_payload *upayload, *spayload; 82 struct user_key_payload *upayload, *spayload;
95 int ret; 83 int ret;
@@ -112,6 +100,8 @@ static int user_duplicate(struct key *key, const struct key *source)
112 100
113} /* end user_duplicate() */ 101} /* end user_duplicate() */
114 102
103EXPORT_SYMBOL_GPL(user_duplicate);
104
115/*****************************************************************************/ 105/*****************************************************************************/
116/* 106/*
117 * dispose of the old data from an updated user defined key 107 * dispose of the old data from an updated user defined key
@@ -131,7 +121,7 @@ static void user_update_rcu_disposal(struct rcu_head *rcu)
131 * update a user defined key 121 * update a user defined key
132 * - the key's semaphore is write-locked 122 * - the key's semaphore is write-locked
133 */ 123 */
134static int user_update(struct key *key, const void *data, size_t datalen) 124int user_update(struct key *key, const void *data, size_t datalen)
135{ 125{
136 struct user_key_payload *upayload, *zap; 126 struct user_key_payload *upayload, *zap;
137 int ret; 127 int ret;
@@ -163,26 +153,30 @@ static int user_update(struct key *key, const void *data, size_t datalen)
163 153
164 call_rcu(&zap->rcu, user_update_rcu_disposal); 154 call_rcu(&zap->rcu, user_update_rcu_disposal);
165 155
166 error: 156error:
167 return ret; 157 return ret;
168 158
169} /* end user_update() */ 159} /* end user_update() */
170 160
161EXPORT_SYMBOL_GPL(user_update);
162
171/*****************************************************************************/ 163/*****************************************************************************/
172/* 164/*
173 * match users on their name 165 * match users on their name
174 */ 166 */
175static int user_match(const struct key *key, const void *description) 167int user_match(const struct key *key, const void *description)
176{ 168{
177 return strcmp(key->description, description) == 0; 169 return strcmp(key->description, description) == 0;
178 170
179} /* end user_match() */ 171} /* end user_match() */
180 172
173EXPORT_SYMBOL_GPL(user_match);
174
181/*****************************************************************************/ 175/*****************************************************************************/
182/* 176/*
183 * dispose of the data dangling from the corpse of a user 177 * dispose of the data dangling from the corpse of a user
184 */ 178 */
185static void user_destroy(struct key *key) 179void user_destroy(struct key *key)
186{ 180{
187 struct user_key_payload *upayload = key->payload.data; 181 struct user_key_payload *upayload = key->payload.data;
188 182
@@ -190,11 +184,13 @@ static void user_destroy(struct key *key)
190 184
191} /* end user_destroy() */ 185} /* end user_destroy() */
192 186
187EXPORT_SYMBOL_GPL(user_destroy);
188
193/*****************************************************************************/ 189/*****************************************************************************/
194/* 190/*
195 * describe the user key 191 * describe the user key
196 */ 192 */
197static void user_describe(const struct key *key, struct seq_file *m) 193void user_describe(const struct key *key, struct seq_file *m)
198{ 194{
199 seq_puts(m, key->description); 195 seq_puts(m, key->description);
200 196
@@ -202,13 +198,14 @@ static void user_describe(const struct key *key, struct seq_file *m)
202 198
203} /* end user_describe() */ 199} /* end user_describe() */
204 200
201EXPORT_SYMBOL_GPL(user_describe);
202
205/*****************************************************************************/ 203/*****************************************************************************/
206/* 204/*
207 * read the key data 205 * read the key data
208 * - the key's semaphore is read-locked 206 * - the key's semaphore is read-locked
209 */ 207 */
210static long user_read(const struct key *key, 208long user_read(const struct key *key, char __user *buffer, size_t buflen)
211 char __user *buffer, size_t buflen)
212{ 209{
213 struct user_key_payload *upayload; 210 struct user_key_payload *upayload;
214 long ret; 211 long ret;
@@ -228,3 +225,5 @@ static long user_read(const struct key *key,
228 return ret; 225 return ret;
229 226
230} /* end user_read() */ 227} /* end user_read() */
228
229EXPORT_SYMBOL_GPL(user_read);