-
Notifications
You must be signed in to change notification settings - Fork 1.8k
in_forward: fix connection release on pause memory corruption #11114
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
base: master
Are you sure you want to change the base?
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 |
|---|---|---|
|
|
@@ -124,28 +124,37 @@ static int fw_unix_create(struct flb_in_fw_config *ctx) | |
| static int in_fw_collect(struct flb_input_instance *ins, | ||
| struct flb_config *config, void *in_context) | ||
| { | ||
| int state_backup; | ||
| struct flb_connection *connection; | ||
| struct fw_conn *conn; | ||
| struct flb_in_fw_config *ctx; | ||
|
|
||
| ctx = in_context; | ||
|
|
||
| state_backup = ctx->state; | ||
| ctx->state = FW_INSTANCE_STATE_ACCEPTING_CLIENT; | ||
|
|
||
| connection = flb_downstream_conn_get(ctx->downstream); | ||
|
|
||
| if (connection == NULL) { | ||
| flb_plg_error(ctx->ins, "could not accept new connection"); | ||
| ctx->state = state_backup; | ||
|
|
||
| return -1; | ||
| } | ||
|
|
||
| if (!config->is_ingestion_active) { | ||
| flb_downstream_conn_release(connection); | ||
| ctx->state = state_backup; | ||
|
|
||
| return -1; | ||
| } | ||
|
|
||
| if(ctx->is_paused) { | ||
| flb_downstream_conn_release(connection); | ||
| flb_plg_trace(ins, "TCP connection will be closed FD=%i", connection->fd); | ||
| ctx->state = state_backup; | ||
|
|
||
| return -1; | ||
| } | ||
|
|
||
|
|
@@ -154,9 +163,17 @@ static int in_fw_collect(struct flb_input_instance *ins, | |
| conn = fw_conn_add(connection, ctx); | ||
| if (!conn) { | ||
| flb_downstream_conn_release(connection); | ||
| ctx->state = state_backup; | ||
|
|
||
| return -1; | ||
| } | ||
|
|
||
| ctx->state = state_backup; | ||
|
|
||
| if (ctx->state == FW_INSTANCE_STATE_PAUSED) { | ||
| fw_conn_del_all(ctx); | ||
|
Comment on lines
+171
to
+174
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.
After pausing, Useful? React with 👍 / 👎.
Author
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. I dont think this is a valid problem because in if(ctx->is_paused) {
flb_downstream_conn_release(connection);
flb_plg_trace(ins, "TCP connection will be closed FD=%i", connection->fd);
ctx->state = state_backup;
return -1;
} |
||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
|
|
@@ -263,6 +280,7 @@ static int in_fw_init(struct flb_input_instance *ins, | |
| return -1; | ||
| } | ||
|
|
||
| ctx->state = FW_INSTANCE_STATE_RUNNING; | ||
| ctx->coll_fd = -1; | ||
| ctx->ins = ins; | ||
| mk_list_init(&ctx->connections); | ||
|
|
@@ -386,7 +404,10 @@ static void in_fw_pause(void *data, struct flb_config *config) | |
| return; | ||
| } | ||
|
|
||
| fw_conn_del_all(ctx); | ||
| if (ctx->state == FW_INSTANCE_STATE_RUNNING) { | ||
| fw_conn_del_all(ctx); | ||
| } | ||
|
Comment on lines
+407
to
+409
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. State check under mutex but state write outside creates inconsistency. Line 407 reads
Result: The mutex protects Move the state assignment inside the mutex-protected region: ret = pthread_mutex_lock(&ctx->conn_mutex);
if (ret != 0) {
flb_plg_error(ctx->ins, "cannot lock collector mutex");
return;
}
if (ctx->state == FW_INSTANCE_STATE_RUNNING) {
fw_conn_del_all(ctx);
}
ctx->is_paused = FLB_TRUE;
+ ctx->state = FW_INSTANCE_STATE_PAUSED;
ret = pthread_mutex_unlock(&ctx->conn_mutex);
if (ret != 0) {
flb_plg_error(ctx->ins, "cannot unlock collector mutex");
return;
}
}
/*
* If the plugin is paused AND the ingestion not longer active,
* it means we are in a shutdown phase. This plugin can safetly
* close the socket server collector.
*
* This socket stop is a workaround since the server API will be
* refactored shortly.
*/
if (config->is_ingestion_active == FLB_FALSE) {
fw_conn_del_all(ctx);
}
-
- ctx->state = FW_INSTANCE_STATE_PAUSED;Also update Also applies to: 431-431 🤖 Prompt for AI Agents |
||
|
|
||
| ctx->is_paused = FLB_TRUE; | ||
| ret = pthread_mutex_unlock(&ctx->conn_mutex); | ||
| if (ret != 0) { | ||
|
|
@@ -406,6 +427,8 @@ static void in_fw_pause(void *data, struct flb_config *config) | |
| if (config->is_ingestion_active == FLB_FALSE) { | ||
| fw_conn_del_all(ctx); | ||
| } | ||
|
|
||
| ctx->state = FW_INSTANCE_STATE_PAUSED; | ||
| } | ||
|
|
||
| static void in_fw_resume(void *data, struct flb_config *config) { | ||
|
|
@@ -427,6 +450,8 @@ static void in_fw_resume(void *data, struct flb_config *config) { | |
| flb_plg_error(ctx->ins, "cannot unlock collector mutex"); | ||
| return; | ||
| } | ||
|
|
||
| ctx->state = FW_INSTANCE_STATE_RUNNING; | ||
|
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. State assignment should be under mutex protection. Line 454 writes Move the state assignment inside the mutex: ret = pthread_mutex_lock(&ctx->conn_mutex);
if (ret != 0) {
flb_plg_error(ctx->ins, "cannot lock collector mutex");
return;
}
ctx->is_paused = FLB_FALSE;
+ ctx->state = FW_INSTANCE_STATE_RUNNING;
ret = pthread_mutex_unlock(&ctx->conn_mutex);
if (ret != 0) {
flb_plg_error(ctx->ins, "cannot unlock collector mutex");
return;
}
-
- ctx->state = FW_INSTANCE_STATE_RUNNING;
}🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,12 @@ | |
| #include <fluent-bit/flb_log_event_decoder.h> | ||
| #include <fluent-bit/flb_log_event_encoder.h> | ||
|
|
||
| #define FW_INSTANCE_STATE_RUNNING 0 | ||
| #define FW_INSTANCE_STATE_ACCEPTING_CLIENT 1 | ||
| #define FW_INSTANCE_STATE_PROCESSING_PACKET 2 | ||
| #define FW_INSTANCE_STATE_PAUSED 3 | ||
|
Comment on lines
+28
to
+31
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. State field lacks synchronization primitives or access discipline. The new
This creates data races where one thread's state transition can be lost or observed partially by another thread. Apply one of these approaches: Option 1: Use existing conn_mutex consistently struct flb_in_fw_config {
...
struct flb_log_event_encoder *log_encoder;
pthread_mutex_t conn_mutex;
+ /* Protected by conn_mutex */
int state;
/* Plugin is paused */
int is_paused;
};Then ensure all state reads/writes in fw.c and fw_conn.c acquire Option 2: Use C11 atomics +#include <stdatomic.h>
+
struct flb_in_fw_config {
...
pthread_mutex_t conn_mutex;
- int state;
+ _Atomic int state;Then replace direct assignments with Also applies to: 85-86 🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| enum { | ||
| FW_HANDSHAKE_HELO = 1, | ||
| FW_HANDSHAKE_PINGPONG = 2, | ||
|
|
@@ -76,6 +82,8 @@ struct flb_in_fw_config { | |
|
|
||
| pthread_mutex_t conn_mutex; | ||
|
|
||
| int state; | ||
|
|
||
| /* Plugin is paused */ | ||
| int is_paused; | ||
| }; | ||
|
|
||
This comment was marked as off-topic.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.