hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/net/dns_resolver/dns_key.c
....@@ -1,6 +1,6 @@
11 /* Key type used to cache DNS lookups made by the kernel
22 *
3
- * See Documentation/networking/dns_resolver.txt
3
+ * See Documentation/networking/dns_resolver.rst
44 *
55 * Copyright (c) 2007 Igor Mammedov
66 * Author(s): Igor Mammedov (niallain@gmail.com)
....@@ -29,6 +29,7 @@
2929 #include <linux/keyctl.h>
3030 #include <linux/err.h>
3131 #include <linux/seq_file.h>
32
+#include <linux/dns_resolver.h>
3233 #include <keys/dns_resolver-type.h>
3334 #include <keys/user-type.h>
3435 #include "internal.h"
....@@ -48,27 +49,86 @@
4849 /*
4950 * Preparse instantiation data for a dns_resolver key.
5051 *
51
- * The data must be a NUL-terminated string, with the NUL char accounted in
52
- * datalen.
52
+ * For normal hostname lookups, the data must be a NUL-terminated string, with
53
+ * the NUL char accounted in datalen.
5354 *
5455 * If the data contains a '#' characters, then we take the clause after each
5556 * one to be an option of the form 'key=value'. The actual data of interest is
5657 * the string leading up to the first '#'. For instance:
5758 *
5859 * "ip1,ip2,...#foo=bar"
60
+ *
61
+ * For server list requests, the data must begin with a NUL char and be
62
+ * followed by a byte indicating the version of the data format. Version 1
63
+ * looks something like (note this is packed):
64
+ *
65
+ * u8 Non-string marker (ie. 0)
66
+ * u8 Content (DNS_PAYLOAD_IS_*)
67
+ * u8 Version (e.g. 1)
68
+ * u8 Source of server list
69
+ * u8 Lookup status of server list
70
+ * u8 Number of servers
71
+ * foreach-server {
72
+ * __le16 Name length
73
+ * __le16 Priority (as per SRV record, low first)
74
+ * __le16 Weight (as per SRV record, higher first)
75
+ * __le16 Port
76
+ * u8 Source of address list
77
+ * u8 Lookup status of address list
78
+ * u8 Protocol (DNS_SERVER_PROTOCOL_*)
79
+ * u8 Number of addresses
80
+ * char[] Name (not NUL-terminated)
81
+ * foreach-address {
82
+ * u8 Family (DNS_ADDRESS_IS_*)
83
+ * union {
84
+ * u8[4] ipv4_addr
85
+ * u8[16] ipv6_addr
86
+ * }
87
+ * }
88
+ * }
89
+ *
5990 */
6091 static int
6192 dns_resolver_preparse(struct key_preparsed_payload *prep)
6293 {
94
+ const struct dns_payload_header *bin;
6395 struct user_key_payload *upayload;
6496 unsigned long derrno;
6597 int ret;
6698 int datalen = prep->datalen, result_len = 0;
6799 const char *data = prep->data, *end, *opt;
68100
101
+ if (datalen <= 1 || !data)
102
+ return -EINVAL;
103
+
104
+ if (data[0] == 0) {
105
+ /* It may be a server list. */
106
+ if (datalen <= sizeof(*bin))
107
+ return -EINVAL;
108
+
109
+ bin = (const struct dns_payload_header *)data;
110
+ kenter("[%u,%u],%u", bin->content, bin->version, datalen);
111
+ if (bin->content != DNS_PAYLOAD_IS_SERVER_LIST) {
112
+ pr_warn_ratelimited(
113
+ "dns_resolver: Unsupported content type (%u)\n",
114
+ bin->content);
115
+ return -EINVAL;
116
+ }
117
+
118
+ if (bin->version != 1) {
119
+ pr_warn_ratelimited(
120
+ "dns_resolver: Unsupported server list version (%u)\n",
121
+ bin->version);
122
+ return -EINVAL;
123
+ }
124
+
125
+ result_len = datalen;
126
+ goto store_result;
127
+ }
128
+
69129 kenter("'%*.*s',%u", datalen, datalen, data, datalen);
70130
71
- if (datalen <= 1 || !data || data[datalen - 1] != '\0')
131
+ if (!data || data[datalen - 1] != '\0')
72132 return -EINVAL;
73133 datalen--;
74134
....@@ -144,6 +204,7 @@
144204 return 0;
145205 }
146206
207
+store_result:
147208 kdebug("store result");
148209 prep->quotalen = result_len;
149210
....@@ -253,6 +314,7 @@
253314
254315 struct key_type key_type_dns_resolver = {
255316 .name = "dns_resolver",
317
+ .flags = KEY_TYPE_NET_DOMAIN,
256318 .preparse = dns_resolver_preparse,
257319 .free_preparse = dns_resolver_free_preparse,
258320 .instantiate = generic_key_instantiate,