java-topology/defects/telegraf/patch/telegraf-0001-dedup-getfield-quadratic.patch

45 lines
1.7 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UNDF: UNDF-2026-000000822
# UNDF: (leave blank)
# CWE-407: Dedup processor Apply() uses GetField O(F) inside field loop → O(F²)
#
# In plugins/processors/dedup/dedup.go, the Apply() method compares each field
# of an incoming metric against the cached metric by calling m.GetField(f.Key)
# which performs a linear scan of the cached metric's field list. For each
# incoming metric, this is O(F_new × F_cached) ≈ O(F²).
#
# Fix: Build a map from the cached metric's fields for O(1) lookup, reducing
# the overall comparison to O(F).
#
# Severity: MEDIUM — Telegraf metrics typically have 10-50 fields, but
# system/CPU/disk metrics can exceed 100 fields. The dedup processor is a
# common pipeline component.
#
--- a/plugins/processors/dedup/dedup.go
+++ b/plugins/processors/dedup/dedup.go
@@ -31,6 +31,14 @@ func (d *Dedup) Apply(metrics ...telegraf.Metric) []telegraf.Metric {
idx := 0
for _, metric := range metrics {
id := metric.HashID()
m, ok := d.cache[id]
// If not in cache then just save it
@@ -53,8 +61,15 @@ func (d *Dedup) Apply(metrics ...telegraf.Metric) []telegraf.Metric {
// For each field compare value with the cached one
changed := false
added := false
sametime := metric.Time() == m.Time()
+
+ // Build a map of cached fields for O(1) lookup instead of
+ // calling m.GetField() which is O(F) per call
+ cachedFields := make(map[string]interface{}, len(m.FieldList()))
+ for _, cf := range m.FieldList() {
+ cachedFields[cf.Key] = cf.Value
+ }
+
for _, f := range metric.FieldList() {
- if value, ok := m.GetField(f.Key); ok {
+ if value, ok := cachedFields[f.Key]; ok {
if value != f.Value {
changed = true
break