@cryptotaxi247 / netdata-1 / commits / d3c055074

log2journal: fix config parsing memory leaks (#18893)

* fix memory leaks * cleanup parsing of booleans

Costa Tsaousis committed Oct 29, 2024 at 23:50 UTC d3c055074c232725496d121eaf9e3b3cb05e436c
5 files changed +190 -127
src/collectors/log2journal/log2journal-params.c
+6
@@ -47,6 +47,12 @@ void log_job_cleanup(LOG_JOB *jb) {
47 for(size_t i = 0; i < jb->rewrites.used; i++)
48 rewrite_cleanup(&jb->rewrites.array[i]);
49
50 + search_pattern_cleanup(&jb->filter.include);
51 + search_pattern_cleanup(&jb->filter.exclude);
52 +
53 + hashed_key_cleanup(&jb->filename.key);
54 + hashed_key_cleanup(&jb->unmatched.key);
55 +
56 txt_cleanup(&jb->rewrites.tmp);
57 txt_cleanup(&jb->filename.current);
58
src/collectors/log2journal/log2journal-pcre2.c
+8 -1
@@ -102,8 +102,15 @@ PCRE2_STATE *pcre2_parser_create(LOG_JOB *jb) {
102 }
103
104 void pcre2_parser_destroy(PCRE2_STATE *pcre2) {
105 - if(pcre2)
105 + if(pcre2) {
106 + if(pcre2->re)
107 + pcre2_code_free(pcre2->re);
108 +
109 + if(pcre2->match_data)
110 + pcre2_match_data_free(pcre2->match_data);
111 +
112 freez(pcre2);
113 + }
114 }
115
116 const char *pcre2_parser_error(PCRE2_STATE *pcre2) {
src/collectors/log2journal/log2journal-rewrite.c
+1
@@ -7,6 +7,7 @@ void rewrite_cleanup(REWRITE *rw) {
7
8 if(rw->flags & RW_MATCH_PCRE2)
9 search_pattern_cleanup(&rw->match_pcre2);
10 +
11 else if(rw->flags & RW_MATCH_NON_EMPTY)
12 replace_pattern_cleanup(&rw->match_non_empty);
13
src/collectors/log2journal/log2journal-yaml.c
+168 -120
@@ -280,6 +280,8 @@ static bool yaml_parse_constant_field_injection(yaml_parser_t *parser, LOG_JOB *
280 goto cleanup;
281 }
282
283 + yaml_event_delete(&event);
284 +
285 if (!yaml_parse(parser, &event) || event.type != YAML_SCALAR_EVENT) {
286 yaml_error(parser, &event, "Expected scalar for constant field injection value");
287 goto cleanup;
@@ -315,7 +317,7 @@ static bool yaml_parse_injection_mapping(yaml_parser_t *parser, LOG_JOB *jb, boo
317 switch (event.type) {
318 case YAML_SCALAR_EVENT:
319 if (yaml_scalar_matches(&event, "key", strlen("key"))) {
318 - errors += yaml_parse_constant_field_injection(parser, jb, unmatched);
320 + errors += yaml_parse_constant_field_injection(parser, jb, unmatched) ? 1 : 0;
321 } else {
322 yaml_error(parser, &event, "Unexpected scalar in injection mapping");
323 errors++;
@@ -427,6 +429,149 @@ static size_t yaml_parse_unmatched(yaml_parser_t *parser, LOG_JOB *jb) {
429 return errors;
430 }
431
432 +static bool yaml_parse_scalar_boolean(yaml_parser_t *parser, bool def, const char *where, size_t *errors) {
433 + bool rc = def;
434 +
435 + yaml_event_t value_event;
436 + if (!yaml_parse(parser, &value_event)) {
437 + (*errors)++;
438 + return rc;
439 + }
440 +
441 + if (value_event.type != YAML_SCALAR_EVENT) {
442 + yaml_error(parser, &value_event, "Expected scalar for %s boolean", where);
443 + (*errors)++;
444 + }
445 + else if(strncmp((char*)value_event.data.scalar.value, "yes", 3) == 0 ||
446 + strncmp((char*)value_event.data.scalar.value, "true", 4) == 0)
447 + rc = true;
448 + else if(strncmp((char*)value_event.data.scalar.value, "no", 2) == 0 ||
449 + strncmp((char*)value_event.data.scalar.value, "false", 5) == 0)
450 + rc = false;
451 + else {
452 + yaml_error(parser, &value_event, "Expected scalar for %s boolean: invalid value %s", where, value_event.data.scalar.value);
453 + rc = def;
454 + }
455 +
456 + yaml_event_delete(&value_event);
457 + return rc;
458 +}
459 +
460 +static bool handle_rewrite_event(yaml_parser_t *parser, yaml_event_t *event,
461 + char **key, char **search_pattern, char **replace_pattern,
462 + RW_FLAGS *flags, bool *mapping_finished,
463 + LOG_JOB *jb, size_t *errors) {
464 + switch (event->type) {
465 + case YAML_SCALAR_EVENT:
466 + if (yaml_scalar_matches(event, "key", strlen("key"))) {
467 + yaml_event_t value_event;
468 + if (!yaml_parse(parser, &value_event)) {
469 + (*errors)++;
470 + return false;
471 + }
472 +
473 + if (value_event.type != YAML_SCALAR_EVENT) {
474 + yaml_error(parser, &value_event, "Expected scalar for rewrite key");
475 + (*errors)++;
476 + } else {
477 + freez(*key);
478 + *key = strndupz((char *)value_event.data.scalar.value, value_event.data.scalar.length);
479 + }
480 + yaml_event_delete(&value_event);
481 + }
482 + else if (yaml_scalar_matches(event, "match", strlen("match"))) {
483 + yaml_event_t value_event;
484 + if (!yaml_parse(parser, &value_event)) {
485 + (*errors)++;
486 + return false;
487 + }
488 +
489 + if (value_event.type != YAML_SCALAR_EVENT) {
490 + yaml_error(parser, &value_event, "Expected scalar for rewrite match PCRE2 pattern");
491 + (*errors)++;
492 + }
493 + else {
494 + freez(*search_pattern);
495 + *flags |= RW_MATCH_PCRE2;
496 + *flags &= ~RW_MATCH_NON_EMPTY;
497 + *search_pattern = strndupz((char *)value_event.data.scalar.value, value_event.data.scalar.length);
498 + }
499 + yaml_event_delete(&value_event);
500 + }
501 + else if (yaml_scalar_matches(event, "not_empty", strlen("not_empty"))) {
502 + yaml_event_t value_event;
503 + if (!yaml_parse(parser, &value_event)) {
504 + (*errors)++;
505 + return false;
506 + }
507 +
508 + if (value_event.type != YAML_SCALAR_EVENT) {
509 + yaml_error(parser, &value_event, "Expected scalar for rewrite not empty condition");
510 + (*errors)++;
511 + }
512 + else {
513 + freez(*search_pattern);
514 + *flags |= RW_MATCH_NON_EMPTY;
515 + *flags &= ~RW_MATCH_PCRE2;
516 + *search_pattern = strndupz((char *)value_event.data.scalar.value, value_event.data.scalar.length);
517 + }
518 + yaml_event_delete(&value_event);
519 + }
520 + else if (yaml_scalar_matches(event, "value", strlen("value"))) {
521 + yaml_event_t value_event;
522 + if (!yaml_parse(parser, &value_event)) {
523 + (*errors)++;
524 + return false;
525 + }
526 +
527 + if (value_event.type != YAML_SCALAR_EVENT) {
528 + yaml_error(parser, &value_event, "Expected scalar for rewrite value");
529 + (*errors)++;
530 + } else {
531 + freez(*replace_pattern);
532 + *replace_pattern = strndupz((char *)value_event.data.scalar.value, value_event.data.scalar.length);
533 + }
534 + yaml_event_delete(&value_event);
535 + }
536 + else if (yaml_scalar_matches(event, "stop", strlen("stop"))) {
537 + if(yaml_parse_scalar_boolean(parser, true, "rewrite stop", errors))
538 + *flags &= ~RW_DONT_STOP;
539 + else
540 + *flags |= RW_DONT_STOP;
541 + }
542 + else if (yaml_scalar_matches(event, "inject", strlen("inject"))) {
543 + if(yaml_parse_scalar_boolean(parser, false, "rewrite inject", errors))
544 + *flags |= RW_INJECT;
545 + else
546 + *flags &= ~RW_INJECT;
547 + }
548 + else {
549 + yaml_error(parser, event, "Unexpected scalar in rewrite mapping");
550 + (*errors)++;
551 + }
552 + break;
553 +
554 + case YAML_MAPPING_END_EVENT:
555 + if(*key) {
556 + if (!log_job_rewrite_add(jb, *key, *flags, *search_pattern, *replace_pattern))
557 + (*errors)++;
558 + }
559 +
560 + freez(*key);
561 + freez(*search_pattern);
562 + freez(*replace_pattern);
563 + *mapping_finished = true;
564 + break;
565 +
566 + default:
567 + yaml_error(parser, event, "Unexpected event in rewrite mapping");
568 + (*errors)++;
569 + break;
570 + }
571 +
572 + return true;
573 +}
574 +
575 static size_t yaml_parse_rewrites(yaml_parser_t *parser, LOG_JOB *jb) {
576 size_t errors = 0;
577
@@ -457,120 +602,14 @@ static size_t yaml_parse_rewrites(yaml_parser_t *parser, LOG_JOB *jb) {
602 continue;
603 }
604
460 - switch (sub_event.type) {
461 - case YAML_SCALAR_EVENT:
462 - if (yaml_scalar_matches(&sub_event, "key", strlen("key"))) {
463 - if (!yaml_parse(parser, &sub_event) || sub_event.type != YAML_SCALAR_EVENT) {
464 - yaml_error(parser, &sub_event, "Expected scalar for rewrite key");
465 - errors++;
466 - } else {
467 - freez(key);
468 - key = strndupz((char *)sub_event.data.scalar.value, sub_event.data.scalar.length);
469 - yaml_event_delete(&sub_event);
470 - }
471 - } else if (yaml_scalar_matches(&sub_event, "match", strlen("match"))) {
472 - if (!yaml_parse(parser, &sub_event) || sub_event.type != YAML_SCALAR_EVENT) {
473 - yaml_error(parser, &sub_event, "Expected scalar for rewrite match PCRE2 pattern");
474 - errors++;
475 - }
476 - else {
477 - if(search_pattern)
478 - freez(search_pattern);
479 - flags |= RW_MATCH_PCRE2;
480 - flags &= ~RW_MATCH_NON_EMPTY;
481 - search_pattern = strndupz((char *)sub_event.data.scalar.value, sub_event.data.scalar.length);
482 - yaml_event_delete(&sub_event);
483 - }
484 - } else if (yaml_scalar_matches(&sub_event, "not_empty", strlen("not_empty"))) {
485 - if (!yaml_parse(parser, &sub_event) || sub_event.type != YAML_SCALAR_EVENT) {
486 - yaml_error(parser, &sub_event, "Expected scalar for rewrite not empty condition");
487 - errors++;
488 - }
489 - else {
490 - if(search_pattern)
491 - freez(search_pattern);
492 - flags |= RW_MATCH_NON_EMPTY;
493 - flags &= ~RW_MATCH_PCRE2;
494 - search_pattern = strndupz((char *)sub_event.data.scalar.value, sub_event.data.scalar.length);
495 - yaml_event_delete(&sub_event);
496 - }
497 - } else if (yaml_scalar_matches(&sub_event, "value", strlen("value"))) {
498 - if (!yaml_parse(parser, &sub_event) || sub_event.type != YAML_SCALAR_EVENT) {
499 - yaml_error(parser, &sub_event, "Expected scalar for rewrite value");
500 - errors++;
501 - } else {
502 - freez(replace_pattern);
503 - replace_pattern = strndupz((char *)sub_event.data.scalar.value, sub_event.data.scalar.length);
504 - yaml_event_delete(&sub_event);
505 - }
506 - } else if (yaml_scalar_matches(&sub_event, "stop", strlen("stop"))) {
507 - if (!yaml_parse(parser, &sub_event) || sub_event.type != YAML_SCALAR_EVENT) {
508 - yaml_error(parser, &sub_event, "Expected scalar for rewrite stop boolean");
509 - errors++;
510 - } else {
511 - if(strncmp((char*)sub_event.data.scalar.value, "no", 2) == 0 ||
512 - strncmp((char*)sub_event.data.scalar.value, "false", 5) == 0)
513 - flags |= RW_DONT_STOP;
514 - else
515 - flags &= ~RW_DONT_STOP;
516 -
517 - yaml_event_delete(&sub_event);
518 - }
519 - } else if (yaml_scalar_matches(&sub_event, "inject", strlen("inject"))) {
520 - if (!yaml_parse(parser, &sub_event) || sub_event.type != YAML_SCALAR_EVENT) {
521 - yaml_error(parser, &sub_event, "Expected scalar for rewrite inject boolean");
522 - errors++;
523 - } else {
524 - if(strncmp((char*)sub_event.data.scalar.value, "yes", 3) == 0 ||
525 - strncmp((char*)sub_event.data.scalar.value, "true", 4) == 0)
526 - flags |= RW_INJECT;
527 - else
528 - flags &= ~RW_INJECT;
529 -
530 - yaml_event_delete(&sub_event);
531 - }
532 - } else {
533 - yaml_error(parser, &sub_event, "Unexpected scalar in rewrite mapping");
534 - errors++;
535 - }
536 - break;
537 -
538 - case YAML_MAPPING_END_EVENT:
539 - if(key) {
540 - if (!log_job_rewrite_add(jb, key, flags, search_pattern, replace_pattern))
541 - errors++;
542 - }
543 -
544 - freez(key);
545 - key = NULL;
546 -
547 - freez(search_pattern);
548 - search_pattern = NULL;
549 -
550 - freez(replace_pattern);
551 - replace_pattern = NULL;
552 -
553 - flags = RW_NONE;
554 -
555 - mapping_finished = true;
556 - break;
557 -
558 - default:
559 - yaml_error(parser, &sub_event, "Unexpected event in rewrite mapping");
560 - errors++;
561 - break;
562 - }
605 + handle_rewrite_event(parser, &sub_event, &key,
606 + &search_pattern, &replace_pattern,
607 + &flags, &mapping_finished, jb, &errors);
608
609 yaml_event_delete(&sub_event);
610 }
566 - freez(replace_pattern);
567 - replace_pattern = NULL;
568 - freez(search_pattern);
569 - search_pattern = NULL;
570 - freez(key);
571 - key = NULL;
572 - }
611 break;
612 + }
613
614 case YAML_SEQUENCE_END_EVENT:
615 finished = true;
@@ -618,25 +657,30 @@ static size_t yaml_parse_renames(yaml_parser_t *parser, LOG_JOB *jb) {
657 switch (sub_event.type) {
658 case YAML_SCALAR_EVENT:
659 if (yaml_scalar_matches(&sub_event, "new_key", strlen("new_key"))) {
621 - if (!yaml_parse(parser, &sub_event) || sub_event.type != YAML_SCALAR_EVENT) {
622 - yaml_error(parser, &sub_event, "Expected scalar for rename new_key");
660 + yaml_event_t value_event;
661 +
662 + if (!yaml_parse(parser, &value_event) || value_event.type != YAML_SCALAR_EVENT) {
663 + yaml_error(parser, &value_event, "Expected scalar for rename new_key");
664 errors++;
665 } else {
625 - hashed_key_len_set(&rn.new_key, (char *)sub_event.data.scalar.value, sub_event.data.scalar.length);
626 - yaml_event_delete(&sub_event);
666 + hashed_key_len_set(&rn.new_key, (char *)value_event.data.scalar.value, value_event.data.scalar.length);
667 + yaml_event_delete(&value_event);
668 }
669 } else if (yaml_scalar_matches(&sub_event, "old_key", strlen("old_key"))) {
629 - if (!yaml_parse(parser, &sub_event) || sub_event.type != YAML_SCALAR_EVENT) {
630 - yaml_error(parser, &sub_event, "Expected scalar for rename old_key");
670 + yaml_event_t value_event;
671 +
672 + if (!yaml_parse(parser, &value_event) || value_event.type != YAML_SCALAR_EVENT) {
673 + yaml_error(parser, &value_event, "Expected scalar for rename old_key");
674 errors++;
675 } else {
633 - hashed_key_len_set(&rn.old_key, (char *)sub_event.data.scalar.value, sub_event.data.scalar.length);
634 - yaml_event_delete(&sub_event);
676 + hashed_key_len_set(&rn.old_key, (char *)value_event.data.scalar.value, value_event.data.scalar.length);
677 + yaml_event_delete(&value_event);
678 }
679 } else {
680 yaml_error(parser, &sub_event, "Unexpected scalar in rewrite mapping");
681 errors++;
682 }
683 +
684 break;
685
686 case YAML_MAPPING_END_EVENT:
@@ -793,7 +837,11 @@ bool yaml_parse_file(const char *config_file_path, LOG_JOB *jb) {
837 }
838
839 yaml_parser_t parser;
796 - yaml_parser_initialize(&parser);
840 + if (!yaml_parser_initialize(&parser)) {
841 + fclose(fp);
842 + return false;
843 + }
844 +
845 yaml_parser_set_input_file(&parser, fp);
846
847 size_t errors = yaml_parse_initialized(&parser, jb);
src/collectors/log2journal/log2journal.h
+7 -6
@@ -245,7 +245,7 @@ typedef enum __attribute__((__packed__)) {
245
246 HK_HASHTABLE_ALLOCATED = (1 << 0), // this is key object allocated in the hashtable
247 // objects that do not have this, have a pointer to a key in the hashtable
248 - // objects that have this, value a value allocated
248 + // objects that have this, value is allocated
249
250 HK_FILTERED = (1 << 1), // we checked once if this key in filtered
251 HK_FILTERED_INCLUDED = (1 << 2), // the result of the filtering was to include it in the output
@@ -274,15 +274,16 @@ typedef struct hashed_key {
274 } HASHED_KEY;
275
276 static inline void hashed_key_cleanup(HASHED_KEY *k) {
277 - if(k->key) {
278 - freez((void *)k->key);
279 - k->key = NULL;
280 - }
281 -
277 if(k->flags & HK_HASHTABLE_ALLOCATED)
278 txt_cleanup(&k->value);
279 else
280 k->hashtable_ptr = NULL;
281 +
282 + freez((void *)k->key);
283 + k->key = NULL;
284 + k->len = 0;
285 + k->hash = 0;
286 + k->flags = HK_NONE;
287 }
288
289 static inline void hashed_key_set(HASHED_KEY *k, const char *name) {