Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/config_format/flb_cf_fluentbit.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,7 @@ struct flb_cf *flb_cf_fluentbit_create(struct flb_cf *cf,
char *file_path, char *buf, size_t size)
{
int ret;
int cf_created = FLB_FALSE;
struct local_ctx ctx;
ino_t ino_table[FLB_CF_FILE_NUM_LIMIT];
int ino_num = 0;
Expand All @@ -781,13 +782,14 @@ struct flb_cf *flb_cf_fluentbit_create(struct flb_cf *cf,
if (!cf) {
return NULL;
}
cf_created = FLB_TRUE;

flb_cf_set_origin_format(cf, FLB_CF_CLASSIC);
}

ret = local_init(&ctx, file_path);
if (ret != 0) {
if (cf) {
if (cf_created == FLB_TRUE) {
flb_cf_destroy(cf);
}
return NULL;
Expand All @@ -798,7 +800,9 @@ struct flb_cf *flb_cf_fluentbit_create(struct flb_cf *cf,
local_exit(&ctx);

if (ret == -1) {
flb_cf_destroy(cf);
if (cf_created == FLB_TRUE) {
flb_cf_destroy(cf);
}
Comment on lines +803 to +805

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep a pointer to caller-owned cf on failure

When parsing fails for a caller-owned config, this path now returns NULL without freeing cf, but hot reload still does new_cf = flb_cf_create_from_file(new_cf, file) in src/flb_reload.c:554 and then returns on !new_cf, losing the only pointer to the caller-owned config object. A bad reload config, such as a missing include, will now leak that new_cf and any reconstructed CLI config stored in it on every failed reload attempt; use a temporary return value or update the error path to destroy the original caller-owned object.

Useful? React with 👍 / 👎.

if (ino_num >= FLB_CF_FILE_NUM_LIMIT) {
flb_error("Too many config files. Limit = %d", FLB_CF_FILE_NUM_LIMIT);
}
Expand Down
10 changes: 8 additions & 2 deletions src/config_format/flb_cf_yaml.c
Original file line number Diff line number Diff line change
Expand Up @@ -3188,13 +3188,15 @@ struct flb_cf *flb_cf_yaml_create(struct flb_cf *conf, char *file_path,
char *buf, size_t size)
{
int ret;
int conf_created = FLB_FALSE;
struct local_ctx ctx;

if (!conf) {
conf = flb_cf_create();
if (!conf) {
return NULL;
}
conf_created = FLB_TRUE;
flb_cf_set_origin_format(conf, FLB_CF_YAML);
}
else {
Expand All @@ -3205,15 +3207,19 @@ struct flb_cf *flb_cf_yaml_create(struct flb_cf *conf, char *file_path,
ret = local_init(&ctx);

if (ret == -1) {
flb_cf_destroy(conf);
if (conf_created == FLB_TRUE) {
flb_cf_destroy(conf);
}
return NULL;
}

/* process the entry poing config file */
ret = read_config(conf, &ctx, NULL, file_path);

if (ret == -1) {
flb_cf_destroy(conf);
if (conf_created == FLB_TRUE) {
flb_cf_destroy(conf);
}
local_exit(&ctx);
return NULL;
}
Expand Down
9 changes: 7 additions & 2 deletions src/flb_reload.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts)
struct flb_config *new_config;
flb_ctx_t *new_ctx = NULL;
struct flb_cf *new_cf;
struct flb_cf *loaded_cf;
struct flb_cf *original_cf;
int verbose;
int reloaded_count = 0;
Expand Down Expand Up @@ -551,14 +552,18 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts)

/* Create another config format context */
if (file != NULL) {
new_cf = flb_cf_create_from_file(new_cf, file);
loaded_cf = flb_cf_create_from_file(new_cf, file);

if (!new_cf) {
if (!loaded_cf) {
flb_sds_destroy(file);
flb_cf_destroy(new_cf);
flb_destroy(new_ctx);
old_config->hot_reloading = FLB_FALSE;
flb_reload_watchdog_cleanup(watchdog_ctx);
return FLB_RELOAD_HALTED;
}

new_cf = loaded_cf;
}

/* Load external plugins via command line */
Expand Down
45 changes: 34 additions & 11 deletions tests/internal/config_format_fluentbit.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define FLB_003 FLB_TESTS_DATA_PATH "/data/config_format/classic/recursion.conf"
#define FLB_004 FLB_TESTS_DATA_PATH "/data/config_format/classic/issue6281.conf"
#define FLB_005 FLB_TESTS_DATA_PATH "/data/config_format/classic/nolimitline.conf"
#define FLB_006 FLB_TESTS_DATA_PATH "/data/config_format/classic/missing_include.conf"

#define ERROR_LOG "fluentbit_conf_error.log"

Expand Down Expand Up @@ -166,7 +167,8 @@ void missing_value()

void indent_level_error()
{
struct flb_cf *cf;
struct flb_cf *cf;
struct flb_cf *ret;
FILE *fp = NULL;
char *expected_strs[] = {"invalid", "indent", "level"};
struct str_list expected = {
Expand All @@ -188,44 +190,64 @@ void indent_level_error()
exit(EXIT_FAILURE);
}

cf = flb_cf_fluentbit_create(cf, FLB_002, NULL, 0);
TEST_CHECK(cf == NULL);
ret = flb_cf_fluentbit_create(cf, FLB_002, NULL, 0);
TEST_CHECK(ret == NULL);
fflush(fp);
fclose(fp);

fp = fopen(ERROR_LOG, "r");
if (!TEST_CHECK(fp != NULL)) {
TEST_MSG("fopen failed. errno=%d path=%s", errno, ERROR_LOG);
if (cf != NULL) {
flb_cf_destroy(cf);
}
flb_cf_destroy(cf);
unlink(ERROR_LOG);
exit(EXIT_FAILURE);
}

check_str_list(&expected, fp);
if (cf != NULL) {
flb_cf_destroy(cf);
}
flb_cf_destroy(cf);
fclose(fp);
unlink(ERROR_LOG);
}

void recursion()
{
struct flb_cf *cf;
struct flb_cf *cf;
struct flb_cf *ret;

cf = flb_cf_create();
if (!TEST_CHECK(cf != NULL)) {
TEST_MSG("flb_cf_create failed");
exit(EXIT_FAILURE);
}

cf = flb_cf_fluentbit_create(cf, FLB_003, NULL, 0);
ret = flb_cf_fluentbit_create(cf, FLB_003, NULL, 0);
if (ret != NULL) {
flb_cf_destroy(ret);
}
else {
flb_cf_destroy(cf);
}

/* No SIGSEGV means success */
}

void test_caller_owned_error()
{
struct flb_cf *cf;
struct flb_cf *ret;

cf = flb_cf_create();
if (!TEST_CHECK(cf != NULL)) {
TEST_MSG("flb_cf_create failed");
exit(EXIT_FAILURE);
}

ret = flb_cf_fluentbit_create(cf, FLB_006, NULL, 0);
TEST_CHECK(ret == NULL);

flb_cf_destroy(cf);
}


/*
* https://github.com/fluent/fluent-bit/issues/6281
Expand Down Expand Up @@ -346,6 +368,7 @@ TEST_LIST = {
{ "missing_value_issue5880" , missing_value},
{ "indent_level_error" , indent_level_error},
{ "recursion" , recursion},
{ "caller_owned_error" , test_caller_owned_error},
{ "not_current_dir_files", not_current_dir_files},
{ "no_limit_line", test_nolimit_line},
{ "snake_case_key", test_snake_case_key},
Expand Down
19 changes: 19 additions & 0 deletions tests/internal/config_format_yaml.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define FLB_004 FLB_TESTS_CONF_PATH "/stream_processor.yaml"
#define FLB_005 FLB_TESTS_CONF_PATH "/plugins.yaml"
#define FLB_006 FLB_TESTS_CONF_PATH "/upstream.yaml"
#define FLB_007 FLB_TESTS_CONF_PATH "/missing_include.yaml"

#define FLB_000_WIN FLB_TESTS_CONF_PATH "\\fluent-bit-windows.yaml"
#define FLB_BROKEN_PLUGIN_VARIANT FLB_TESTS_CONF_PATH "/broken_plugin_variant.yaml"
Expand Down Expand Up @@ -873,6 +874,23 @@ static void test_invalid_property()
}
}

static void test_caller_owned_error()
{
struct flb_cf *cf;
struct flb_cf *ret;

cf = flb_cf_create();
if (!TEST_CHECK(cf != NULL)) {
TEST_MSG("flb_cf_create failed");
exit(EXIT_FAILURE);
}

ret = flb_cf_yaml_create(cf, FLB_007, NULL, 0);
TEST_CHECK(ret == NULL);

flb_cf_destroy(cf);
}

TEST_LIST = {
{ "basic" , test_basic},
{ "customs section", test_customs_section},
Expand All @@ -887,5 +905,6 @@ TEST_LIST = {
{ "plugins", test_plugins},
{ "upstream_servers", test_upstream_servers},
{ "invalid_input_property", test_invalid_property},
{ "caller_owned_error", test_caller_owned_error},
{ 0 }
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@INCLUDE missing.conf
2 changes: 2 additions & 0 deletions tests/internal/data/config_format/yaml/missing_include.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
includes:
- missing.yaml
2 changes: 2 additions & 0 deletions tests/internal/data/reload/yaml/missing_include.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
includes:
- missing_reload_include.yaml
60 changes: 58 additions & 2 deletions tests/internal/reload.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@

#include "flb_tests_internal.h"

#define FLB_YAML FLB_TESTS_DATA_PATH "/data/reload/yaml/processor.yaml"
#define FLB_CLASSIC FLB_TESTS_DATA_PATH "/data/reload/fluent-bit.conf"
#define FLB_YAML FLB_TESTS_DATA_PATH "/data/reload/yaml/processor.yaml"
#define FLB_YAML_MISSING_INCLUDE FLB_TESTS_DATA_PATH "/data/reload/yaml/missing_include.yaml"
#define FLB_CLASSIC FLB_TESTS_DATA_PATH "/data/reload/fluent-bit.conf"

void test_reconstruct_cf()
{
Expand Down Expand Up @@ -247,6 +248,60 @@ void test_reload_yaml()
flb_destroy(ctx);
}

/* data/reload/yaml/missing_include.yaml */
void test_reload_yaml_missing_include()
{
struct flb_cf *cf = NULL;
struct flb_cf *cf_opts;
struct flb_cf_section *section;
struct cfl_variant *ret;
flb_ctx_t *ctx;
int status;

cf_opts = flb_cf_create();
TEST_CHECK(cf_opts != NULL);

section = flb_cf_section_create(cf_opts, "INPUT", 5);
TEST_CHECK(section != NULL);

ret = flb_cf_section_property_add(cf_opts, section->properties, "name", 0, "dummy", 0);
TEST_CHECK(ret != NULL);

ctx = flb_create();
if (!TEST_CHECK(ctx != NULL)) {
TEST_MSG("flb_create failed");
exit(EXIT_FAILURE);
}

cf = ctx->config->cf_main;

status = flb_reload_reconstruct_cf(cf_opts, cf);
TEST_CHECK(status == 0);

cf = flb_cf_create_from_file(cf, FLB_YAML);
TEST_CHECK(cf != NULL);

ctx->config->conf_path_file = flb_sds_create(FLB_YAML);
ctx->config->enable_hot_reload = FLB_TRUE;

status = flb_config_load_config_format(ctx->config, cf);
TEST_CHECK(status == 0);

status = flb_start(ctx);
TEST_CHECK(status == 0);

flb_sds_destroy(ctx->config->conf_path_file);
ctx->config->conf_path_file = flb_sds_create(FLB_YAML_MISSING_INCLUDE);

status = flb_reload(ctx, cf_opts);
TEST_CHECK(status == FLB_RELOAD_HALTED);

flb_cf_destroy(cf_opts);

flb_stop(ctx);
flb_destroy(ctx);
}

/* Test hot reload watchdog timeout functionality */
#ifndef FLB_SYSTEM_WINDOWS
void test_reload_watchdog_timeout()
Expand Down Expand Up @@ -394,6 +449,7 @@ TEST_LIST = {
{ "reconstruct_cf" , test_reconstruct_cf},
{ "reload" , test_reload},
{ "reload_yaml" , test_reload_yaml},
{ "reload_yaml_missing_include", test_reload_yaml_missing_include},
{ "reload_watchdog_timeout", test_reload_watchdog_timeout},
{ 0 }
};
Loading