@cryptotaxi247 / netdata-1 / commits / a121c3bbb

Added protection against URL and name length abuse.

Costa Tsaousis committed May 11, 2016 at 15:13 UTC a121c3bbb713be2825b0d643f74226d16a5f9249
1 file changed +33 -2
src/registry.c
+33 -2
@@ -2,8 +2,6 @@
2 #include <config.h>
3 #endif
4
5 -// gcc -O1 -ggdb -Wall -Wextra -I ../src/ -I ../ -o registry ../src/registry.c ../src/dictionary.o ../src/log.o ../src/avl.o ../src/common.o ../src/appconfig.o ../src/web_buffer.o ../src/storage_number.o -pthread -luuid -lm -DHAVE_CONFIG_H -DVARLIB_DIR="\"/tmp\""
6 -
5 #include <uuid/uuid.h>
6 #include <inttypes.h>
7 #include <stdlib.h>
@@ -34,6 +32,13 @@
32 // database should be cleaned in registry_save() for both on-disk and
33 // on-memory entries.
34 //
35 +// Cleanup:
36 +// i. Find all the PERSONs that have expired cookie
37 +// ii. For each of their PERSON_URLs:
38 +// - decrement the linked MACHINE links
39 +// - if the linked MACHINE has no other links, remove the linked MACHINE too
40 +// - remove the PERSON_URL
41 +//
42 // 2. add protection to prevent abusing the registry by flooding it with
43 // requests to fill the memory and crash it.
44 //
@@ -42,6 +47,8 @@
47 // - limit the number of URLs per machine
48 // - limit the number of persons
49 // - limit the number of machines
50 +// - [DONE] limit the size of URLs
51 +// - [DONE] limit the size of PERSON_URL names
52 // - limit the number of requests that add data to the registry,
53 // per client IP per hour
54
@@ -83,6 +90,9 @@ struct registry {
90 char *registry_to_announce;
91 time_t persons_expiration; // seconds to expire idle persons
92
93 + size_t max_url_length;
94 + size_t max_name_length;
95 +
96 // file/path names
97 char *pathname;
98 char *db_filename;
@@ -142,6 +152,8 @@ typedef struct machine_url MACHINE_URL;
152 struct machine {
153 char guid[36 + 1]; // the GUID
154
155 + uint32_t links; // the number of PERSON_URLs linked to this machine
156 +
157 DICTIONARY *urls; // MACHINE_URL *
158
159 uint32_t first_t; // the first time we saw this
@@ -318,6 +330,10 @@ extern PERSON *registry_request_delete(char *person_guid, char *machine_guid, ch
330 // URL
331
332 static inline URL *registry_url_allocate_nolock(const char *url, size_t urllen) {
333 + // protection from too big URLs
334 + if(urllen > registry.max_url_length)
335 + urllen = registry.max_url_length;
336 +
337 debug(D_REGISTRY, "Registry: registry_url_allocate_nolock('%s'): allocating %zu bytes", url, sizeof(URL) + urllen);
338 URL *u = malloc(sizeof(URL) + urllen);
339 if(!u) fatal("Cannot allocate %zu bytes for URL '%s'", sizeof(URL) + urllen);
@@ -461,6 +477,10 @@ static inline PERSON *registry_person_find(const char *person_guid) {
477 }
478
479 static inline PERSON_URL *registry_person_url_allocate(PERSON *p, MACHINE *m, URL *u, char *name, size_t namelen, time_t when) {
480 + // protection from too big names
481 + if(namelen > registry.max_name_length)
482 + namelen = registry.max_name_length;
483 +
484 debug(D_REGISTRY, "registry_person_url_allocate('%s', '%s', '%s'): allocating %zu bytes", p->guid, m->guid, u->url,
485 sizeof(PERSON_URL) + namelen);
486
@@ -477,6 +497,7 @@ static inline PERSON_URL *registry_person_url_allocate(PERSON *p, MACHINE *m, UR
497 pu->usages = 1;
498 pu->url = u;
499 pu->flags = REGISTRY_URL_FLAGS_DEFAULT;
500 + m->links++;
501
502 registry.persons_urls_memory += sizeof(PERSON_URL) + namelen;
503
@@ -500,6 +521,7 @@ static inline PERSON_URL *registry_person_url_reallocate(PERSON *p, MACHINE *m,
521
522 // ok, these are a hack - since the registry_person_url_allocate() is
523 // adding these, we have to subtract them
524 + tpu->machine->links--;
525 registry.persons_urls_memory -= sizeof(PERSON_URL) + strlen(pu->name);
526 registry_url_unlink_nolock(u);
527
@@ -607,7 +629,12 @@ static inline PERSON_URL *registry_person_link_to_url(PERSON *p, MACHINE *m, URL
629 p->guid, m->guid, u->url, pu->machine->guid);
630 mu->flags |= REGISTRY_URL_FLAGS_EXPIRED;
631 }
632 + else {
633 + info("registry_person_link_to_url('%s', '%s', '%s'): URL switched machines (old was '%s') - but the URL is not linked to the old machine.",
634 + p->guid, m->guid, u->url, pu->machine->guid);
635 + }
636
637 + pu->machine->links--;
638 pu->machine = m;
639 }
640
@@ -1554,6 +1581,10 @@ int registry_init(void) {
1581 registry.registry_to_announce = config_get("registry", "registry to announce", "https://registry.netdata.online");
1582 registry.hostname = config_get("registry", "registry hostname", config_get("global", "hostname", hostname));
1583
1584 + registry.max_url_length = config_get("registry", "max URL length", 1024);
1585 + registry.max_name_length = config_get("registry", "max URL name length", 50);
1586 +
1587 +
1588 // initialize entries counters
1589 registry.persons_count = 0;
1590 registry.machines_count = 0;