summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-12-10 15:01:04 +0100
committerLennart Poettering <lennart@poettering.net>2015-12-11 14:14:27 +0100
commitc463eb783e5ad999d400180c69b912c54fa07ee1 (patch)
treefad08bb02ce0d915adfed3be0ea9604e9d87ebb1
parente6b57b378709af68d1828e26aec684f88bd04172 (diff)
resolved: generalize DNS RR type validity checks
Check the validity of RR types as we parse or receive data from IPC clients, and use the same code for all of them.
-rw-r--r--src/resolve/dns-type.c22
-rw-r--r--src/resolve/dns-type.h5
-rw-r--r--src/resolve/resolved-bus.c3
-rw-r--r--src/resolve/resolved-dns-packet.c9
-rw-r--r--src/resolve/resolved-dns-transaction.c4
5 files changed, 37 insertions, 6 deletions
diff --git a/src/resolve/dns-type.c b/src/resolve/dns-type.c
index 8ce8a566f1..8281da3b7c 100644
--- a/src/resolve/dns-type.c
+++ b/src/resolve/dns-type.c
@@ -63,3 +63,25 @@ bool dns_type_is_pseudo(uint16_t type) {
DNS_TYPE_TKEY
);
}
+
+bool dns_type_is_valid_query(uint16_t type) {
+
+ /* The types valid as questions in packets */
+
+ return !IN_SET(type,
+ 0,
+ DNS_TYPE_OPT,
+ DNS_TYPE_TSIG,
+ DNS_TYPE_TKEY);
+}
+
+bool dns_type_is_valid_rr(uint16_t type) {
+
+ /* The types valid as RR in packets (but not necessarily
+ * stored on servers). */
+
+ return !IN_SET(type,
+ DNS_TYPE_ANY,
+ DNS_TYPE_AXFR,
+ DNS_TYPE_IXFR);
+}
diff --git a/src/resolve/dns-type.h b/src/resolve/dns-type.h
index 2868025ad7..038a0d0e54 100644
--- a/src/resolve/dns-type.h
+++ b/src/resolve/dns-type.h
@@ -25,7 +25,10 @@
const char *dns_type_to_string(int type);
int dns_type_from_string(const char *s);
-bool dns_type_is_pseudo(uint16_t n);
+
+bool dns_type_is_pseudo(uint16_t type);
+bool dns_type_is_valid_query(uint16_t type);
+bool dns_type_is_valid_rr(uint16_t type);
/* DNS record types, taken from
* http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml.
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index 1427638233..c8c0d3d9b8 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -553,6 +553,9 @@ static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd
if (r == 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid name '%s'", name);
+ if (!dns_type_is_valid_query(type))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid RR type for query %" PRIu16, type);
+
r = check_ifindex_flags(ifindex, &flags, 0, error);
if (r < 0)
return r;
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
index 7c5be538b8..4e069ab4cb 100644
--- a/src/resolve/resolved-dns-packet.c
+++ b/src/resolve/resolved-dns-packet.c
@@ -1525,9 +1525,7 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
goto fail;
if (key->class == DNS_CLASS_ANY ||
- key->type == DNS_TYPE_ANY ||
- key->type == DNS_TYPE_AXFR ||
- key->type == DNS_TYPE_IXFR) {
+ !dns_type_is_valid_rr(key->type)) {
r = -EBADMSG;
goto fail;
}
@@ -1971,6 +1969,11 @@ int dns_packet_extract(DnsPacket *p) {
if (r < 0)
goto finish;
+ if (!dns_type_is_valid_query(key->type)) {
+ r = -EBADMSG;
+ goto finish;
+ }
+
r = dns_question_add(question, key);
if (r < 0)
goto finish;
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index bcf6d5c810..5cd03bc01d 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -107,11 +107,11 @@ int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key)
assert(key);
/* Don't allow looking up invalid or pseudo RRs */
- if (IN_SET(key->type, DNS_TYPE_OPT, 0, DNS_TYPE_TSIG, DNS_TYPE_TKEY))
+ if (!dns_type_is_valid_query(key->type))
return -EINVAL;
/* We only support the IN class */
- if (key->class != DNS_CLASS_IN)
+ if (key->class != DNS_CLASS_IN && key->class != DNS_CLASS_ANY)
return -EOPNOTSUPP;
r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL);