summaryrefslogtreecommitdiff
path: root/src/resolve
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-11-24 21:39:14 +0100
committerLennart Poettering <lennart@poettering.net>2015-11-25 21:58:38 +0100
commiteed857b71702f8551b46b66b31fa0d08583cf23c (patch)
tree519b8597bd9f187e6656b4e60ea8a0ea38b88a64 /src/resolve
parent4b95f1798f22c1bb75295f448188560cb6ec9ece (diff)
resolved: enforce a maximum limit on both dns servers and search domains
Diffstat (limited to 'src/resolve')
-rw-r--r--src/resolve/resolved-dns-search-domain.c22
-rw-r--r--src/resolve/resolved-dns-server.c30
-rw-r--r--src/resolve/resolved-link.h5
-rw-r--r--src/resolve/resolved-manager.h5
4 files changed, 50 insertions, 12 deletions
diff --git a/src/resolve/resolved-dns-search-domain.c b/src/resolve/resolved-dns-search-domain.c
index 5d927bb2a1..d8a0648aab 100644
--- a/src/resolve/resolved-dns-search-domain.c
+++ b/src/resolve/resolved-dns-search-domain.c
@@ -31,7 +31,7 @@ int dns_search_domain_new(
const char *name) {
_cleanup_free_ char *normalized = NULL;
- DnsSearchDomain *d, *tail;
+ DnsSearchDomain *d;
int r;
assert(m);
@@ -48,6 +48,14 @@ int dns_search_domain_new(
if (r > 0)
return -EINVAL;
+ if (l) {
+ if (l->n_search_domains >= LINK_SEARCH_DOMAINS_MAX)
+ return -E2BIG;
+ } else {
+ if (m->n_search_domains >= MANAGER_SEARCH_DOMAINS_MAX)
+ return -E2BIG;
+ }
+
d = new0(DnsSearchDomain, 1);
if (!d)
return -ENOMEM;
@@ -62,13 +70,13 @@ int dns_search_domain_new(
case DNS_SEARCH_DOMAIN_LINK:
d->link = l;
- LIST_FIND_TAIL(domains, l->search_domains, tail);
- LIST_INSERT_AFTER(domains, l->search_domains, tail, d);
+ LIST_APPEND(domains, l->search_domains, d);
+ l->n_search_domains++;
break;
case DNS_SERVER_SYSTEM:
- LIST_FIND_TAIL(domains, m->search_domains, tail);
- LIST_INSERT_AFTER(domains, m->search_domains, tail, d);
+ LIST_APPEND(domains, m->search_domains, d);
+ m->n_search_domains++;
break;
default:
@@ -120,11 +128,15 @@ void dns_search_domain_unlink(DnsSearchDomain *d) {
case DNS_SEARCH_DOMAIN_LINK:
assert(d->link);
+ assert(d->link->n_search_domains > 0);
LIST_REMOVE(domains, d->link->search_domains, d);
+ d->link->n_search_domains--;
break;
case DNS_SEARCH_DOMAIN_SYSTEM:
+ assert(d->manager->n_search_domains > 0);
LIST_REMOVE(domains, d->manager->search_domains, d);
+ d->manager->n_search_domains--;
break;
}
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c
index 93b954139b..0ebd22fe22 100644
--- a/src/resolve/resolved-dns-server.c
+++ b/src/resolve/resolved-dns-server.c
@@ -37,12 +37,23 @@ int dns_server_new(
int family,
const union in_addr_union *in_addr) {
- DnsServer *s, *tail;
+ DnsServer *s;
assert(m);
assert((type == DNS_SERVER_LINK) == !!l);
assert(in_addr);
+ if (!IN_SET(family, AF_INET, AF_INET6))
+ return -EAFNOSUPPORT;
+
+ if (l) {
+ if (l->n_dns_servers >= LINK_DNS_SERVERS_MAX)
+ return -E2BIG;
+ } else {
+ if (m->n_dns_servers >= MANAGER_DNS_SERVERS_MAX)
+ return -E2BIG;
+ }
+
s = new0(DnsServer, 1);
if (!s)
return -ENOMEM;
@@ -58,18 +69,18 @@ int dns_server_new(
case DNS_SERVER_LINK:
s->link = l;
- LIST_FIND_TAIL(servers, l->dns_servers, tail);
- LIST_INSERT_AFTER(servers, l->dns_servers, tail, s);
+ LIST_APPEND(servers, l->dns_servers, s);
+ l->n_dns_servers++;
break;
case DNS_SERVER_SYSTEM:
- LIST_FIND_TAIL(servers, m->dns_servers, tail);
- LIST_INSERT_AFTER(servers, m->dns_servers, tail, s);
+ LIST_APPEND(servers, m->dns_servers, s);
+ m->n_dns_servers++;
break;
case DNS_SERVER_FALLBACK:
- LIST_FIND_TAIL(servers, m->fallback_dns_servers, tail);
- LIST_INSERT_AFTER(servers, m->fallback_dns_servers, tail, s);
+ LIST_APPEND(servers, m->fallback_dns_servers, s);
+ m->n_dns_servers++;
break;
default:
@@ -131,15 +142,20 @@ void dns_server_unlink(DnsServer *s) {
case DNS_SERVER_LINK:
assert(s->link);
+ assert(s->link->n_dns_servers > 0);
LIST_REMOVE(servers, s->link->dns_servers, s);
break;
case DNS_SERVER_SYSTEM:
+ assert(s->manager->n_dns_servers > 0);
LIST_REMOVE(servers, s->manager->dns_servers, s);
+ s->manager->n_dns_servers--;
break;
case DNS_SERVER_FALLBACK:
+ assert(s->manager->n_dns_servers > 0);
LIST_REMOVE(servers, s->manager->fallback_dns_servers, s);
+ s->manager->n_dns_servers--;
break;
}
diff --git a/src/resolve/resolved-link.h b/src/resolve/resolved-link.h
index a25715d269..eb00015bd5 100644
--- a/src/resolve/resolved-link.h
+++ b/src/resolve/resolved-link.h
@@ -34,6 +34,9 @@ typedef struct LinkAddress LinkAddress;
#include "resolved-dns-server.h"
#include "resolved-manager.h"
+#define LINK_SEARCH_DOMAINS_MAX 32
+#define LINK_DNS_SERVERS_MAX 32
+
struct LinkAddress {
Link *link;
@@ -58,8 +61,10 @@ struct Link {
LIST_HEAD(DnsServer, dns_servers);
DnsServer *current_dns_server;
+ unsigned n_dns_servers;
LIST_HEAD(DnsSearchDomain, search_domains);
+ unsigned n_search_domains;
Support llmnr_support;
diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h
index 0683e23f6c..2bbd5d08e9 100644
--- a/src/resolve/resolved-manager.h
+++ b/src/resolve/resolved-manager.h
@@ -45,6 +45,9 @@ enum Support {
#include "resolved-dns-stream.h"
#include "resolved-link.h"
+#define MANAGER_SEARCH_DOMAINS_MAX 32
+#define MANAGER_DNS_SERVERS_MAX 32
+
struct Manager {
sd_event *event;
@@ -70,9 +73,11 @@ struct Manager {
/* Unicast dns */
LIST_HEAD(DnsServer, dns_servers);
LIST_HEAD(DnsServer, fallback_dns_servers);
+ unsigned n_dns_servers; /* counts both main and fallback */
DnsServer *current_dns_server;
LIST_HEAD(DnsSearchDomain, search_domains);
+ unsigned n_search_domains;
bool need_builtin_fallbacks:1;