Fix complilation / enforce size check (#22216)
Enforce context/job name length constraints in pulse-workers to prevent overflow.
Stelios Fragkakis committed
Apr 17, 2026 at 00:01 UTC
acf166ac53f133f97dd9ec3bdc49771cfef0a781
1 file changed
+17
-4
src/daemon/pulse/pulse-workers.c
+17
-4
@@ -120,6 +120,15 @@ struct worker_utilization {
120
RRDDIM *rd_memory_calls[WORKERS_MEMORY_CALL_MAX];
121
};
122
123
+static inline size_t workers_chart_context_job_name_max_length(const char *worker_name_lowercase, const char *metric_type) {
124
+ size_t fixed_length = strlen("netdata.workers.") + strlen(worker_name_lowercase) + strlen(metric_type);
125
+
126
+ if(fixed_length >= RRD_ID_LENGTH_MAX)
127
+ return 0;
128
+
129
+ return RRD_ID_LENGTH_MAX - fixed_length - 1;
130
+}
131
+
132
static struct worker_utilization all_workers_utilization[] = {
133
{ .name = "PULSE", .family = "workers pulse", .priority = 1000000 },
134
{ .name = "HEALTH", .family = "workers health alerts", .priority = 1000000 },
@@ -750,7 +759,8 @@ static void workers_utilization_update_chart(struct worker_utilization *wu) {
759
760
if(!wu->per_job_type[i].st) {
761
size_t job_name_len = string_strlen(wu->per_job_type[i].name);
753
- if(job_name_len > RRD_ID_LENGTH_MAX) job_name_len = RRD_ID_LENGTH_MAX;
762
+ size_t job_name_max_len = workers_chart_context_job_name_max_length(wu->name_lowercase, ".value.");
763
+ if(job_name_len > job_name_max_len) job_name_len = job_name_max_len;
764
765
char job_name_sanitized[RRD_ID_LENGTH_MAX + 1];
766
rrdset_strncpyz_name(job_name_sanitized, string2str(wu->per_job_type[i].name), job_name_len);
@@ -759,7 +769,8 @@ static void workers_utilization_update_chart(struct worker_utilization *wu) {
769
snprintfz(name, RRD_ID_LENGTH_MAX, "workers_%s_value_%s", wu->name_lowercase, job_name_sanitized);
770
771
char context[RRD_ID_LENGTH_MAX + 1];
762
- snprintf(context, RRD_ID_LENGTH_MAX, "netdata.workers.%s.value.%s", wu->name_lowercase, job_name_sanitized);
772
+ size_t context_len = (size_t)snprintfz(context, RRD_ID_LENGTH_MAX + 1, "netdata.workers.%s.value.", wu->name_lowercase);
773
+ strcatz(context, context_len, job_name_sanitized, sizeof(context));
774
775
char title[1000 + 1];
776
snprintf(title, 1000, "Netdata Workers %s value of %s", wu->name_lowercase, string2str(wu->per_job_type[i].name));
@@ -806,7 +817,8 @@ static void workers_utilization_update_chart(struct worker_utilization *wu) {
817
818
if(!wu->per_job_type[i].st) {
819
size_t job_name_len = string_strlen(wu->per_job_type[i].name);
809
- if(job_name_len > RRD_ID_LENGTH_MAX) job_name_len = RRD_ID_LENGTH_MAX;
820
+ size_t job_name_max_len = workers_chart_context_job_name_max_length(wu->name_lowercase, ".rate.");
821
+ if(job_name_len > job_name_max_len) job_name_len = job_name_max_len;
822
823
char job_name_sanitized[RRD_ID_LENGTH_MAX + 1];
824
rrdset_strncpyz_name(job_name_sanitized, string2str(wu->per_job_type[i].name), job_name_len);
@@ -815,7 +827,8 @@ static void workers_utilization_update_chart(struct worker_utilization *wu) {
827
snprintfz(name, RRD_ID_LENGTH_MAX, "workers_%s_rate_%s", wu->name_lowercase, job_name_sanitized);
828
829
char context[RRD_ID_LENGTH_MAX + 1];
818
- snprintf(context, RRD_ID_LENGTH_MAX, "netdata.workers.%s.rate.%s", wu->name_lowercase, job_name_sanitized);
830
+ size_t context_len = (size_t)snprintfz(context, RRD_ID_LENGTH_MAX + 1, "netdata.workers.%s.rate.", wu->name_lowercase);
831
+ strcatz(context, context_len, job_name_sanitized, sizeof(context));
832
833
char title[1000 + 1];
834
snprintf(title, 1000, "Netdata Workers %s rate of %s", wu->name_lowercase, string2str(wu->per_job_type[i].name));