-
Notifications
You must be signed in to change notification settings - Fork 2k
config_format: cf_yaml: fix Windows crash when libyaml is loaded as DLL #11401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2905,7 +2905,7 @@ static int read_config(struct flb_cf *conf, struct local_ctx *ctx, | |
| } | ||
|
|
||
| flb_debug("============ %s ============", cfg_file); | ||
| fh = fopen(include_file, "r"); | ||
| fh = fopen(include_file, "rb"); | ||
|
|
||
| if (!fh) { | ||
| flb_errno(); | ||
|
|
@@ -2925,9 +2925,48 @@ static int read_config(struct flb_cf *conf, struct local_ctx *ctx, | |
| return -1; | ||
| } | ||
| ctx->level++; | ||
|
|
||
| /* | ||
| * On Windows, passing FILE* across DLL boundaries can cause crashes due to | ||
| * different C runtime libraries. Read the file into a buffer and use | ||
| * yaml_parser_set_input_string() instead of yaml_parser_set_input_file(). | ||
| */ | ||
| { | ||
| long file_size; | ||
| unsigned char *file_buffer = NULL; | ||
| size_t bytes_read; | ||
|
|
||
| /* Get file size */ | ||
| fseek(fh, 0, SEEK_END); | ||
| file_size = ftell(fh); | ||
| fseek(fh, 0, SEEK_SET); | ||
|
|
||
| if (file_size < 0) { | ||
| flb_error("[config] could not determine file size for %s", cfg_file); | ||
| fclose(fh); | ||
| flb_sds_destroy(include_dir); | ||
| flb_sds_destroy(include_file); | ||
| return -1; | ||
| } | ||
|
|
||
| /* Allocate buffer */ | ||
| file_buffer = flb_malloc(file_size + 1); | ||
| if (!file_buffer) { | ||
| flb_error("[config] could not allocate memory for config file %s", cfg_file); | ||
| fclose(fh); | ||
| flb_sds_destroy(include_dir); | ||
| flb_sds_destroy(include_file); | ||
| return -1; | ||
| } | ||
|
|
||
| /* Read file content */ | ||
| bytes_read = fread(file_buffer, 1, file_size, fh); | ||
| fclose(fh); | ||
| fh = NULL; /* Mark as closed */ | ||
| file_buffer[bytes_read] = '\0'; | ||
|
|
||
|
Comment on lines
+2934
to
+2967
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error checking after fread() to detect incomplete reads. The code reads the file content but doesn't verify that the expected number of bytes were actually read. If 🔍 Proposed fix to add fread validation /* Read file content */
bytes_read = fread(file_buffer, 1, file_size, fh);
+ if (bytes_read != (size_t)file_size) {
+ flb_error("[config] failed to read complete file %s: expected %ld bytes, got %zu bytes",
+ cfg_file, file_size, bytes_read);
+ if (ferror(fh)) {
+ flb_error("[config] I/O error occurred while reading %s", cfg_file);
+ }
+ flb_free(file_buffer);
+ fclose(fh);
+ flb_sds_destroy(include_dir);
+ flb_sds_destroy(include_file);
+ return -1;
+ }
fclose(fh);
fh = NULL; /* Mark as closed */
file_buffer[bytes_read] = '\0';🤖 Prompt for AI Agents |
||
| yaml_parser_initialize(&parser); | ||
| yaml_parser_set_input_file(&parser, fh); | ||
| yaml_parser_set_input_string(&parser, file_buffer, bytes_read); | ||
|
|
||
| do { | ||
| status = yaml_parser_parse(&parser, &event); | ||
|
|
@@ -2990,7 +3029,10 @@ static int read_config(struct flb_cf *conf, struct local_ctx *ctx, | |
| state = state_pop(ctx); | ||
| } | ||
|
|
||
| fclose(fh); | ||
| /* Free the file buffer that was allocated for yaml_parser_set_input_string */ | ||
| flb_free(file_buffer); | ||
| } /* End of block that declared file_buffer */ | ||
|
|
||
| ctx->level--; | ||
|
|
||
| flb_sds_destroy(include_file); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new buffered read path never checks whether
freadconsumed the fullfile_sizeor whetherferror()was set. If an I/O error or concurrent truncation yields a short read, the parser will consume a truncated buffer and may succeed silently, leaving Fluent Bit running with an incomplete configuration. Please validatebytes_read == file_size(or checkferror) and fail the parse on short reads to preserve the prior behavior of surfacing read errors.Useful? React with 👍 / 👎.