resolved: enforce a maximum limit on both dns servers and search domains
authorLennart Poettering <lennart@poettering.net>
Tue, 24 Nov 2015 20:39:14 +0000 (21:39 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 25 Nov 2015 20:58:38 +0000 (21:58 +0100)
src/resolve/resolved-dns-search-domain.c
src/resolve/resolved-dns-server.c
src/resolve/resolved-link.h
src/resolve/resolved-manager.h

index 5d927bb..d8a0648 100644 (file)
@@ -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;
         }
 
index 93b9541..0ebd22f 100644 (file)
@@ -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;
         }
 
index a25715d..eb00015 100644 (file)
@@ -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;
 
index 0683e23..2bbd5d0 100644 (file)
@@ -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;