aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2014-07-18 13:56:36 -0400
committerDavid Howells <dhowells@redhat.com>2014-07-22 16:46:36 -0400
commitd46d494214cabfd03eb836e3a8ff3768d4c51497 (patch)
treefbd32f43b69ef9eb79e1694f1ba38a82ac458732
parent7c3bec0a1f2cba8a01b505f032a75cfb8d5cd56d (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.c43
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 */
60static int 60static int
61dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep) 61dns_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 */
166static 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
235struct key_type key_type_dns_resolver = { 240struct 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,