@cryptotaxi247 / netdata-1 / commits / c21e5cefb

Fix potential use after free in RAM mode (#21809)

* cache uuid in mem_metric_handle to avoid dereferencing potentially freed RRDDIM during metric release (ram mode) * release rrddim metrics after querying oldest and latest times to prevent potential resource leaks (ram mode)

Stelios Fragkakis committed Feb 25, 2026 at 16:46 UTC c21e5cefba4b4beab106c07b739a2f88cfe9388f
1 file changed +5 -2
src/database/ram/rrddim_mem.c
+5 -2
@@ -38,6 +38,7 @@ struct mem_metric_handle {
38 time_t last_updated_s;
39 time_t update_every_s;
40
41 + UUIDMAP_ID uuid_id; // stored locally so cleanup doesn't need rd
42 REFCOUNT refcount;
43 };
44
@@ -66,6 +67,7 @@ STORAGE_METRIC_HANDLE *rrddim_metric_get_or_create(RRDDIM *rd, STORAGE_INSTANCE
67 if(!mh) {
68 mh = callocz(1, sizeof(struct mem_metric_handle));
69 mh->rd = rd;
70 + mh->uuid_id = rd->uuid;
71 mh->refcount = 1;
72 update_metric_handle_from_rrddim(mh, rd);
73 *PValue = mh;
@@ -132,11 +134,10 @@ void rrddim_metric_release(STORAGE_METRIC_HANDLE *smh) {
134 // we can delete it
135
136 int64_t judy_mem = 0;
135 - RRDDIM *rd = mh->rd;
137 netdata_rwlock_wrlock(&rrddim_Judy_rwlock);
138 {
139 JudyAllocThreadPulseReset();
139 - JudyLDel(&rrddim_Judy_array, rd->uuid, PJE0);
140 + JudyLDel(&rrddim_Judy_array, mh->uuid_id, PJE0);
141 judy_mem = JudyAllocThreadPulseGetAndReset();
142 }
143 netdata_rwlock_wrunlock(&rrddim_Judy_rwlock);
@@ -153,6 +154,7 @@ bool rrddim_metric_retention_by_uuid(STORAGE_INSTANCE *si __maybe_unused, nd_uui
154
155 *first_entry_s = rrddim_query_oldest_time_s(smh);
156 *last_entry_s = rrddim_query_latest_time_s(smh);
157 + rrddim_metric_release(smh);
158
159 return true;
160 }
@@ -164,6 +166,7 @@ bool rrddim_metric_retention_by_id(STORAGE_INSTANCE *si __maybe_unused, UUIDMAP_
166
167 *first_entry_s = rrddim_query_oldest_time_s(smh);
168 *last_entry_s = rrddim_query_latest_time_s(smh);
169 + rrddim_metric_release(smh);
170
171 return true;
172 }