Skip to content

Commit d46d494

Browse files
committed
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>
1 parent 7c3bec0 commit d46d494

File tree

1 file changed

+25
-18
lines changed

1 file changed

+25
-18
lines changed

net/dns_resolver/dns_key.c

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const struct cred *dns_resolver_cache;
4646
#define DNS_ERRORNO_OPTION "dnserror"
4747

4848
/*
49-
* Instantiate a user defined key for dns_resolver.
49+
* Preparse instantiation data for a dns_resolver key.
5050
*
5151
* The data must be a NUL-terminated string, with the NUL char accounted in
5252
* datalen.
@@ -58,17 +58,15 @@ const struct cred *dns_resolver_cache;
5858
* "ip1,ip2,...#foo=bar"
5959
*/
6060
static int
61-
dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep)
61+
dns_resolver_preparse(struct key_preparsed_payload *prep)
6262
{
6363
struct user_key_payload *upayload;
6464
unsigned long derrno;
6565
int ret;
66-
size_t datalen = prep->datalen, result_len = 0;
66+
int datalen = prep->datalen, result_len = 0;
6767
const char *data = prep->data, *end, *opt;
6868

69-
kenter("%%%d,%s,'%*.*s',%zu",
70-
key->serial, key->description,
71-
(int)datalen, (int)datalen, data, datalen);
69+
kenter("'%*.*s',%u", datalen, datalen, data, datalen);
7270

7371
if (datalen <= 1 || !data || data[datalen - 1] != '\0')
7472
return -EINVAL;
@@ -95,8 +93,7 @@ dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep)
9593
opt_len = next_opt - opt;
9694
if (!opt_len) {
9795
printk(KERN_WARNING
98-
"Empty option to dns_resolver key %d\n",
99-
key->serial);
96+
"Empty option to dns_resolver key\n");
10097
return -EINVAL;
10198
}
10299

@@ -125,30 +122,28 @@ dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep)
125122
goto bad_option_value;
126123

127124
kdebug("dns error no. = %lu", derrno);
128-
key->type_data.x[0] = -derrno;
125+
prep->type_data[0] = ERR_PTR(-derrno);
129126
continue;
130127
}
131128

132129
bad_option_value:
133130
printk(KERN_WARNING
134-
"Option '%*.*s' to dns_resolver key %d:"
131+
"Option '%*.*s' to dns_resolver key:"
135132
" bad/missing value\n",
136-
opt_nlen, opt_nlen, opt, key->serial);
133+
opt_nlen, opt_nlen, opt);
137134
return -EINVAL;
138135
} while (opt = next_opt + 1, opt < end);
139136
}
140137

141138
/* don't cache the result if we're caching an error saying there's no
142139
* result */
143-
if (key->type_data.x[0]) {
144-
kleave(" = 0 [h_error %ld]", key->type_data.x[0]);
140+
if (prep->type_data[0]) {
141+
kleave(" = 0 [h_error %ld]", PTR_ERR(prep->type_data[0]));
145142
return 0;
146143
}
147144

148145
kdebug("store result");
149-
ret = key_payload_reserve(key, result_len);
150-
if (ret < 0)
151-
return -EINVAL;
146+
prep->quotalen = result_len;
152147

153148
upayload = kmalloc(sizeof(*upayload) + result_len + 1, GFP_KERNEL);
154149
if (!upayload) {
@@ -159,12 +154,22 @@ dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep)
159154
upayload->datalen = result_len;
160155
memcpy(upayload->data, data, result_len);
161156
upayload->data[result_len] = '\0';
162-
rcu_assign_pointer(key->payload.data, upayload);
163157

158+
prep->payload[0] = upayload;
164159
kleave(" = 0");
165160
return 0;
166161
}
167162

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+
168173
/*
169174
* The description is of the form "[<type>:]<domain_name>"
170175
*
@@ -234,7 +239,9 @@ static long dns_resolver_read(const struct key *key,
234239

235240
struct key_type key_type_dns_resolver = {
236241
.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,
238245
.match = dns_resolver_match,
239246
.revoke = user_revoke,
240247
.destroy = user_destroy,

0 commit comments

Comments
 (0)