diff options
author | David Howells <dhowells@redhat.com> | 2011-03-07 10:05:59 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2011-03-07 19:17:15 -0500 |
commit | b9fffa3877a3ebbe0a5ad5a247358e2f7df15b24 (patch) | |
tree | 0f58a92c2616b3663f88935290d32a4c90d57025 | |
parent | 633e804e89464d3875e59de1959a53f9041d3094 (diff) |
KEYS: Add a key type op to permit the key description to be vetted
Add a key type operation to permit the key type to vet the description of a new
key that key_alloc() is about to allocate. The operation may reject the
description if it wishes with an error of its choosing. If it does this, the
key will not be allocated.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Mimi Zohar <zohar@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r-- | Documentation/keys.txt | 7 | ||||
-rw-r--r-- | include/linux/key-type.h | 3 | ||||
-rw-r--r-- | net/rxrpc/ar-key.c | 19 | ||||
-rw-r--r-- | security/keys/key.c | 8 |
4 files changed, 37 insertions, 0 deletions
diff --git a/Documentation/keys.txt b/Documentation/keys.txt index e4dbbdb1bd96..cf68d1fed95d 100644 --- a/Documentation/keys.txt +++ b/Documentation/keys.txt | |||
@@ -1062,6 +1062,13 @@ The structure has a number of fields, some of which are mandatory: | |||
1062 | viable. | 1062 | viable. |
1063 | 1063 | ||
1064 | 1064 | ||
1065 | (*) int (*vet_description)(const char *description); | ||
1066 | |||
1067 | This optional method is called to vet a key description. If the key type | ||
1068 | doesn't approve of the key description, it may return an error, otherwise | ||
1069 | it should return 0. | ||
1070 | |||
1071 | |||
1065 | (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); | 1072 | (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); |
1066 | 1073 | ||
1067 | This method is called to attach a payload to a key during construction. | 1074 | This method is called to attach a payload to a key during construction. |
diff --git a/include/linux/key-type.h b/include/linux/key-type.h index 65833d4d5998..fc8525e838b7 100644 --- a/include/linux/key-type.h +++ b/include/linux/key-type.h | |||
@@ -41,6 +41,9 @@ struct key_type { | |||
41 | */ | 41 | */ |
42 | size_t def_datalen; | 42 | size_t def_datalen; |
43 | 43 | ||
44 | /* vet a description */ | ||
45 | int (*vet_description)(const char *description); | ||
46 | |||
44 | /* instantiate a key of this type | 47 | /* instantiate a key of this type |
45 | * - this method should call key_payload_reserve() to determine if the | 48 | * - this method should call key_payload_reserve() to determine if the |
46 | * user's quota will hold the payload | 49 | * user's quota will hold the payload |
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c index d763793d39de..43ea7de2fc8e 100644 --- a/net/rxrpc/ar-key.c +++ b/net/rxrpc/ar-key.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <keys/user-type.h> | 25 | #include <keys/user-type.h> |
26 | #include "ar-internal.h" | 26 | #include "ar-internal.h" |
27 | 27 | ||
28 | static int rxrpc_vet_description_s(const char *); | ||
28 | static int rxrpc_instantiate(struct key *, const void *, size_t); | 29 | static int rxrpc_instantiate(struct key *, const void *, size_t); |
29 | static int rxrpc_instantiate_s(struct key *, const void *, size_t); | 30 | static int rxrpc_instantiate_s(struct key *, const void *, size_t); |
30 | static void rxrpc_destroy(struct key *); | 31 | static void rxrpc_destroy(struct key *); |
@@ -52,6 +53,7 @@ EXPORT_SYMBOL(key_type_rxrpc); | |||
52 | */ | 53 | */ |
53 | struct key_type key_type_rxrpc_s = { | 54 | struct key_type key_type_rxrpc_s = { |
54 | .name = "rxrpc_s", | 55 | .name = "rxrpc_s", |
56 | .vet_description = rxrpc_vet_description_s, | ||
55 | .instantiate = rxrpc_instantiate_s, | 57 | .instantiate = rxrpc_instantiate_s, |
56 | .match = user_match, | 58 | .match = user_match, |
57 | .destroy = rxrpc_destroy_s, | 59 | .destroy = rxrpc_destroy_s, |
@@ -59,6 +61,23 @@ struct key_type key_type_rxrpc_s = { | |||
59 | }; | 61 | }; |
60 | 62 | ||
61 | /* | 63 | /* |
64 | * Vet the description for an RxRPC server key | ||
65 | */ | ||
66 | static int rxrpc_vet_description_s(const char *desc) | ||
67 | { | ||
68 | unsigned long num; | ||
69 | char *p; | ||
70 | |||
71 | num = simple_strtoul(desc, &p, 10); | ||
72 | if (*p != ':' || num > 65535) | ||
73 | return -EINVAL; | ||
74 | num = simple_strtoul(p + 1, &p, 10); | ||
75 | if (*p || num < 1 || num > 255) | ||
76 | return -EINVAL; | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | /* | ||
62 | * parse an RxKAD type XDR format token | 81 | * parse an RxKAD type XDR format token |
63 | * - the caller guarantees we have at least 4 words | 82 | * - the caller guarantees we have at least 4 words |
64 | */ | 83 | */ |
diff --git a/security/keys/key.c b/security/keys/key.c index 1c2d43dc5107..8e315ef2e88e 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -249,6 +249,14 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
249 | if (!desc || !*desc) | 249 | if (!desc || !*desc) |
250 | goto error; | 250 | goto error; |
251 | 251 | ||
252 | if (type->vet_description) { | ||
253 | ret = type->vet_description(desc); | ||
254 | if (ret < 0) { | ||
255 | key = ERR_PTR(ret); | ||
256 | goto error; | ||
257 | } | ||
258 | } | ||
259 | |||
252 | desclen = strlen(desc) + 1; | 260 | desclen = strlen(desc) + 1; |
253 | quotalen = desclen + type->def_datalen; | 261 | quotalen = desclen + type->def_datalen; |
254 | 262 | ||