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;