CVE-2026-83601 Overview
CVE-2026-83601 is an integer overflow vulnerability [CWE-190] in Netdata, an open source observability tool. An authenticated child agent can send an oversized DIMENSION SLOT value that str2ull_encoded passes without validation to pluginsd_rrddim_put_to_slot in src/plugins.d/pluginsd_internals.h. The unbounded value then reaches prd_array_create in src/database/rrdset-pluginsd-array.h, where the size_t multiplication used for the allocation size can wrap. The wrapped value produces an undersized heap allocation while the original large size is retained, causing the initialization loop to write past the buffer and crash the parent agent. The issue is fixed in version 2.10.4 and nightly build 2.10.0-782-nightly.
Critical Impact
An authenticated child agent can crash the parent Netdata agent through a malformed streaming protocol message, resulting in denial of service for centralized observability infrastructure.
Affected Products
- Netdata versions prior to 2.10.4
- Netdata nightly builds prior to 2.10.0-782-nightly
- Deployments using parent/child streaming with untrusted or compromised child agents
Discovery Timeline
- 2026-09-22 - CVE-2026-83601 published to NVD
- 2026-09-22 - Last updated in NVD database
Technical Details for CVE-2026-83601
Vulnerability Analysis
Netdata parent agents accept streaming input from child agents using the pluginsd protocol. The parser routine pluginsd_parse_rrd_slot extracts a SLOT: token from incoming DIMENSION commands and converts it with str2ull_encoded into an unsigned long long. Before the patch, no upper bound was enforced on the parsed value.
The parsed slot number flows into prd_array_create(size_t size), which allocates sizeof(PRD_ARRAY) + size * sizeof(struct pluginsd_rrddim) bytes. When size is attacker-controlled and sufficiently large, the multiplication overflows size_t and produces a small allocation. The subsequent initialization loop then walks the original (large) logical size, writing beyond the heap allocation and corrupting adjacent memory.
Root Cause
The root cause is missing input validation on a network-supplied numeric field combined with an unchecked size arithmetic in the allocator wrapper. pluginsd_parse_rrd_slot trusted the wire value from str2ull_encoded, and prd_array_create performed the size multiplication without a SIZE_MAX / sizeof(...) guard.
Attack Vector
Exploitation requires an authenticated child agent connection to a parent Netdata instance. The attacker sends a DIMENSION command containing a SLOT: token whose numeric value exceeds PLUGINSD_DIMENSION_SLOT_MAX. The parent parses the oversized slot, computes a wrapped allocation size, and crashes when the initialization loop writes past the heap buffer.
// Patch: src/database/rrdset-pluginsd-array.h
// Create a new array with the specified size and refcount=1
// size is expected to be bounded by the caller: pluginsd slot input is capped at
// the parser (PLUGINSD_DIMENSION_SLOT_MAX) and the no-slots path uses the dimension
// count, so the size multiplication below cannot overflow. The check documents and
// guards that invariant against any future unbounded caller (debug builds only).
static inline PRD_ARRAY *prd_array_create(size_t size) {
internal_fatal(size > (SIZE_MAX - sizeof(PRD_ARRAY)) / sizeof(struct pluginsd_rrddim),
"PRD_ARRAY: requested size %zu would overflow the allocation", size);
PRD_ARRAY *arr = callocz(1, sizeof(PRD_ARRAY) + size * sizeof(struct pluginsd_rrddim));
arr->refcount = 1;
arr->size = size;
Source: GitHub Commit 034a774f
The companion fix in pluginsd_internals.h enforces a compile-time maximum on parsed slots and logs a warning when the wire value exceeds the cap:
// Patch: src/plugins.d/pluginsd_internals.h
static ALWAYS_INLINE ssize_t pluginsd_parse_rrd_slot(char **words, size_t num_words, size_t max_slot) {
internal_fatal(max_slot > (size_t)SSIZE_MAX,
"PLUGINSD: max_slot %zu exceeds SSIZE_MAX", max_slot);
ssize_t slot = -1;
char *id = get_word(words, num_words, 1);
if(id && id[0] == PLUGINSD_KEYWORD_SLOT[0] && id[1] == PLUGINSD_KEYWORD_SLOT[1] &&
id[2] == PLUGINSD_KEYWORD_SLOT[2] && id[3] == PLUGINSD_KEYWORD_SLOT[3] && id[4] == ':') {
unsigned long long parsed_slot = str2ull_encoded(&id[5]);
if(unlikely(parsed_slot > max_slot)) {
nd_log_limit_static_global_var(erl_slot, 1, 0);
nd_log_limit(&erl_slot, NDLS_COLLECTORS, NDLP_WARNING,
"PLUGINSD: ignoring invalid SLOT value '%s' above the supported maximum %zu",
&id[5], max_slot);
Source: GitHub Commit 034a774f
Detection Methods for CVE-2026-83601
Indicators of Compromise
- Unexpected termination or SIGSEGV of the parent netdata process shortly after a child agent connects or reconnects.
- Log entries mentioning PLUGINSD: ignoring invalid SLOT value on patched hosts, indicating a child sent an out-of-range slot.
- Repeated child agent reconnect loops in error.log correlating with parent crash timestamps.
Detection Strategies
- Monitor Netdata parent processes for abnormal exit codes and core dumps consistent with heap corruption.
- Inspect pluginsd stream traffic for DIMENSION lines containing SLOT: tokens with values above PLUGINSD_DIMENSION_SLOT_MAX.
- Correlate parent restarts with the source IP and identity of connected child agents to identify a probable sender.
Monitoring Recommendations
- Enable process-level telemetry on hosts running Netdata parents and alert on unplanned service restarts.
- Ship Netdata error.log and collectors.log to a central logging system and alert on the new slot-validation warning message.
- Track parent/child streaming connection metadata (source, API key, hostname) so that a crash can be attributed to a specific child.
How to Mitigate CVE-2026-83601
Immediate Actions Required
- Upgrade all parent Netdata agents to version 2.10.4 or nightly build 2.10.0-782-nightly or later.
- Rotate streaming API keys used by child agents to invalidate any keys that may be in untrusted hands.
- Restrict inbound access to the parent streaming port (default TCP/19999) to known child IP ranges only.
Patch Information
The fix is delivered in Netdata release v2.10.4 via Pull Request #22598 and commit 034a774f. Full details are published in GitHub Security Advisory GHSA-3qh4-842w-fvrm. The patch bounds parsed slot values against PLUGINSD_DIMENSION_SLOT_MAX and adds an overflow guard in prd_array_create.
Workarounds
- Disable inbound streaming on parent agents until the upgrade can be applied by removing or commenting the [stream] inbound configuration.
- Terminate child streaming sessions originating from untrusted hosts and revoke their API keys in stream.conf.
- Place the parent behind a reverse proxy or firewall that limits streaming connections to a strict allowlist.
# Example: restrict streaming to trusted child subnets in stream.conf
[API_KEY_UUID_HERE]
enabled = yes
allow from = 10.0.0.0/24 10.0.1.0/24
default history = 3600
default memory mode = ram
health enabled by default = auto
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.