diff options
author | David Howells <dhowells@redhat.com> | 2014-07-18 13:56:36 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2014-07-22 16:46:36 -0400 |
commit | d46d494214cabfd03eb836e3a8ff3768d4c51497 (patch) | |
tree | fbd32f43b69ef9eb79e1694f1ba38a82ac458732 | |
parent | 7c3bec0a1f2cba8a01b505f032a75cfb8d5cd56d (diff) |
KEYS: DNS: Use key preparsing
Make use of key preparsing in the DNS resolver so that quota size determination
can take place prior to keyring locking when a key is being added.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Steve Dickson <steved@redhat.com>
Acked-by: Jeff Layton <jlayton@primarydata.com>
-rw-r--r-- | net/dns_resolver/dns_key.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c index bf8584339048..f380b2c58178 100644 --- a/net/dns_resolver/dns_key.c +++ b/net/dns_resolver/dns_key.c | |||
@@ -46,7 +46,7 @@ const struct cred *dns_resolver_cache; | |||
46 | #define DNS_ERRORNO_OPTION "dnserror" | 46 | #define DNS_ERRORNO_OPTION "dnserror" |
47 | 47 | ||
48 | /* | 48 | /* |
49 | * Instantiate a user defined key for dns_resolver. | 49 | * Preparse instantiation data for a dns_resolver key. |
50 | * | 50 | * |
51 | * The data must be a NUL-terminated string, with the NUL char accounted in | 51 | * The data must be a NUL-terminated string, with the NUL char accounted in |
52 | * datalen. | 52 | * datalen. |
@@ -58,17 +58,15 @@ const struct cred *dns_resolver_cache; | |||
58 | * "ip1,ip2,...#foo=bar" | 58 | * "ip1,ip2,...#foo=bar" |
59 | */ | 59 | */ |
60 | static int | 60 | static int |
61 | dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep) | 61 | dns_resolver_preparse(struct key_preparsed_payload *prep) |
62 | { | 62 | { |
63 | struct user_key_payload *upayload; | 63 | struct user_key_payload *upayload; |
64 | unsigned long derrno; | 64 | unsigned long derrno; |
65 | int ret; | 65 | int ret; |
66 | size_t datalen = prep->datalen, result_len = 0; | 66 | int datalen = prep->datalen, result_len = 0; |
67 | const char *data = prep->data, *end, *opt; | 67 | const char *data = prep->data, *end, *opt; |
68 | 68 | ||
69 | kenter("%%%d,%s,'%*.*s',%zu", | 69 | kenter("'%*.*s',%u", datalen, datalen, data, datalen); |
70 | key->serial, key->description, | ||
71 | (int)datalen, (int)datalen, data, datalen); | ||
72 | 70 | ||
73 | if (datalen <= 1 || !data || data[datalen - 1] != '\0') | 71 | if (datalen <= 1 || !data || data[datalen - 1] != '\0') |
74 | return -EINVAL; | 72 | return -EINVAL; |
@@ -95,8 +93,7 @@ dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep) | |||
95 | opt_len = next_opt - opt; | 93 | opt_len = next_opt - opt; |
96 | if (!opt_len) { | 94 | if (!opt_len) { |
97 | printk(KERN_WARNING | 95 | printk(KERN_WARNING |
98 | "Empty option to dns_resolver key %d\n", | 96 | "Empty option to dns_resolver key\n"); |
99 | key->serial); | ||
100 | return -EINVAL; | 97 | return -EINVAL; |
101 | } | 98 | } |
102 | 99 | ||
@@ -125,30 +122,28 @@ dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep) | |||
125 | goto bad_option_value; | 122 | goto bad_option_value; |
126 | 123 | ||
127 | kdebug("dns error no. = %lu", derrno); | 124 | kdebug("dns error no. = %lu", derrno); |
128 | key->type_data.x[0] = -derrno; | 125 | prep->type_data[0] = ERR_PTR(-derrno); |
129 | continue; | 126 | continue; |
130 | } | 127 | } |
131 | 128 | ||
132 | bad_option_value: | 129 | bad_option_value: |
133 | printk(KERN_WARNING | 130 | printk(KERN_WARNING |
134 | "Option '%*.*s' to dns_resolver key %d:" | 131 | "Option '%*.*s' to dns_resolver key:" |
135 | " bad/missing value\n", | 132 | " bad/missing value\n", |
136 | opt_nlen, opt_nlen, opt, key->serial); | 133 | opt_nlen, opt_nlen, opt); |
137 | return -EINVAL; | 134 | return -EINVAL; |
138 | } while (opt = next_opt + 1, opt < end); | 135 | } while (opt = next_opt + 1, opt < end); |
139 | } | 136 | } |
140 | 137 | ||
141 | /* don't cache the result if we're caching an error saying there's no | 138 | /* don't cache the result if we're caching an error saying there's no |
142 | * result */ | 139 | * result */ |
143 | if (key->type_data.x[0]) { | 140 | if (prep->type_data[0]) { |
144 | kleave(" = 0 [h_error %ld]", key->type_data.x[0]); | 141 | kleave(" = 0 [h_error %ld]", PTR_ERR(prep->type_data[0])); |
145 | return 0; | 142 | return 0; |
146 | } | 143 | } |
147 | 144 | ||
148 | kdebug("store result"); | 145 | kdebug("store result"); |
149 | ret = key_payload_reserve(key, result_len); | 146 | prep->quotalen = result_len; |
150 | if (ret < 0) | ||
151 | return -EINVAL; | ||
152 | 147 | ||
153 | upayload = kmalloc(sizeof(*upayload) + result_len + 1, GFP_KERNEL); | 148 | upayload = kmalloc(sizeof(*upayload) + result_len + 1, GFP_KERNEL); |
154 | if (!upayload) { | 149 | if (!upayload) { |
@@ -159,13 +154,23 @@ dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep) | |||
159 | upayload->datalen = result_len; | 154 | upayload->datalen = result_len; |
160 | memcpy(upayload->data, data, result_len); | 155 | memcpy(upayload->data, data, result_len); |
161 | upayload->data[result_len] = '\0'; | 156 | upayload->data[result_len] = '\0'; |
162 | rcu_assign_pointer(key->payload.data, upayload); | ||
163 | 157 | ||
158 | prep->payload[0] = upayload; | ||
164 | kleave(" = 0"); | 159 | kleave(" = 0"); |
165 | return 0; | 160 | return 0; |
166 | } | 161 | } |
167 | 162 | ||
168 | /* | 163 | /* |
164 | * Clean up the preparse data | ||
165 | */ | ||
166 | static void dns_resolver_free_preparse(struct key_preparsed_payload *prep) | ||
167 | { | ||
168 | pr_devel("==>%s()\n", __func__); | ||
169 | |||
170 | kfree(prep->payload[0]); | ||
171 | } | ||
172 | |||
173 | /* | ||
169 | * The description is of the form "[<type>:]<domain_name>" | 174 | * The description is of the form "[<type>:]<domain_name>" |
170 | * | 175 | * |
171 | * The domain name may be a simple name or an absolute domain name (which | 176 | * The domain name may be a simple name or an absolute domain name (which |
@@ -234,7 +239,9 @@ static long dns_resolver_read(const struct key *key, | |||
234 | 239 | ||
235 | struct key_type key_type_dns_resolver = { | 240 | struct key_type key_type_dns_resolver = { |
236 | .name = "dns_resolver", | 241 | .name = "dns_resolver", |
237 | .instantiate = dns_resolver_instantiate, | 242 | .preparse = dns_resolver_preparse, |
243 | .free_preparse = dns_resolver_free_preparse, | ||
244 | .instantiate = generic_key_instantiate, | ||
238 | .match = dns_resolver_match, | 245 | .match = dns_resolver_match, |
239 | .revoke = user_revoke, | 246 | .revoke = user_revoke, |
240 | .destroy = user_destroy, | 247 | .destroy = user_destroy, |