AI_ONLY_REPORT package: rrdtool-1.8.0-20.el10 ------ Summary: Stack buffer overflow in rrdcached CREATE handler via unbounded DS/RRA arguments: `handle_request_create()` appends attacker-controlled `DS:` / `RRA:` tokens to a fixed 128-entry stack array without checking bounds, so a single oversized `CREATE` request can write past the end of `av` and corrupt stack memory. Requirements to exploit: Attacker needs local access to a system running `rrdcached` and permission to connect to a socket that accepts `CREATE` requests. In the reviewed code, the default exposure is the local UNIX socket at `unix:/tmp/rrdcached.sock`; some deployments may also expose TCP sockets via `-L` or `-l`. The attacker then sends a single oversized `CREATE` line containing more than 128 `DS:` / `RRA:` tokens. No user interaction is required. Component affected: `rrdcached` in `rrdtool` - `src/rrd_daemon.c` (`handle_request_create()`) Version affected: `rrdtool-1.8.0-20.el10` (confirmed in the reviewed history); other versions containing the same `handle_request_create()` parser logic are likely affected. Patch available: Proposed fix included in this report (see "Proposed fix"); upstream release status unknown. Version fixed (if any already): unknown Upstream coordination: Not yet notified. CVSS: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - 7.8 (HIGH) AV:L - The reviewed transcript narrows the default exposure to a local UNIX socket rather than an inherently remote network service. AC:L - A single oversized `CREATE` request with more than 128 `DS:` / `RRA:` tokens reaches the vulnerable write. PR:L - The attacker needs local access and permission to connect to a socket that permits `CREATE`. UI:N - No user interaction is required once socket access exists. S:U - Impact remains within the `rrdcached` security scope. C:H - Successful memory corruption could expose data accessible to the daemon process. I:H - Successful memory corruption could modify data accessible to the daemon process. A:H - The daemon can be crashed, and code execution in the daemon context is plausible. Impact: Moderate. This is a real stack-memory corruption flaw in a client-reachable daemon parser, but the reviewed transcript narrows the default attack surface to local UNIX socket access and permission-dependent reachability rather than a default remote unauthenticated service. Once an attacker can reach a permitted socket, exploitation is straightforward and may crash the daemon or potentially execute code in the daemon context. Deployments that expose TCP listeners without access controls would face higher practical risk. Embargo: no Reason: The reviewed transcript narrows the default exposure to local socket access, and practical mitigations exist: restrict socket access, avoid unnecessary TCP listeners, and limit which sockets permit `CREATE`. Per Product Security guidance, moderate issues with practical mitigation are typically not embargoed. Acknowledgement: Aisle Research Steps to reproduce: 1. Build `rrdcached` with AddressSanitizer if available, then start the daemon in the foreground on a UNIX socket, for example: ```bash ./src/rrdcached -g -l unix:/tmp/rrdcached.sock ``` 2. Send one `CREATE` line with more than 128 `DS:` fields and at least one `RRA:` field: ```bash python3 - <<'PY' | socat - UNIX-CONNECT:/tmp/rrdcached.sock ds = " ".join([f"DS:x{i}:GAUGE:1:0:U" for i in range(150)]) print(f"CREATE /tmp/poc.rrd {ds} RRA:AVERAGE:0.5:1:10") PY ``` 3. Observe the result: An ASan build reports a stack out-of-bounds write at `av[ac++]`. A non-ASan build may crash or exhibit undefined memory-corruption behavior. 4. Repeat with 128 or fewer combined `DS:` / `RRA:` entries as a control. The overflow should not occur. Mitigation: Restrict access to the UNIX socket using filesystem permissions and group ownership so untrusted local users cannot connect. Do not expose `rrdcached` on TCP listeners (`-L` / `-l`) unless necessary, and place any such listeners behind network access controls. If reachable sockets do not need `CREATE`, use socket command permissions to deny that command there. Run the daemon as an unprivileged user/group where supported (`-U` / `-G`) to reduce impact. Apply a bounds check that rejects more than 128 `DS:` / `RRA:` arguments, or update once an upstream fix is available. Vulnerability details In `src/rrd_daemon.c`, `handle_request_create()` stores user-controlled `DS:` / `RRA:` tokens in a fixed local array without validating `ac` against the array capacity: ```c int ac = 0; char *av[128]; ... if (!strncmp(tok, "DS:", 3)) { av[ac++] = tok; continue; } if (!strncmp(tok, "RRA:", 4)) { av[ac++] = tok; continue; } ``` `ac` and `av` are later passed onward: ```c status = rrd_create_r2(file, step, last_up, no_overwrite, (const char **) sources, template, ac, (const char **) av); ``` There is no `ac < 128` guard before `av[ac++]`, so more than 128 matching tokens write past the end of the stack array. The reviewed transcript also notes that command parsing accepts a full request line up to `RRD_CMD_MAX` (`4096`), which is sufficient to carry more than 128 short `DS:` tokens in one `CREATE` request. Most relevant CWEs: `CWE-121` (Stack-based Buffer Overflow) `CWE-787` (Out-of-bounds Write) Proposed fix ```diff diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c @@ -2388,6 +2388,7 @@ static int handle_request_create( char *file_copy = NULL, *dir = NULL, *dir2 = NULL; char *tok; int ac = 0; + const int av_max = 128; char *av[128]; @@ -2502,10 +2503,20 @@ static int handle_request_create( continue; } if (!strncmp(tok, "DS:", 3)) { + if (ac >= av_max) { + rc = send_response(sock, RESP_ERR, + "Too many DS/RRA arguments (max %d)\n", + av_max); + goto done; + } av[ac++] = tok; continue; } if (!strncmp(tok, "RRA:", 4)) { + if (ac >= av_max) { + rc = send_response(sock, RESP_ERR, + "Too many DS/RRA arguments (max %d)\n", + av_max); + goto done; + } av[ac++] = tok; continue; } ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use