Skip to content

VNX-124: Buffer Underwrite ('Buffer Underflow')

Reports C/C++ writes that land before a buffer when a length is zero or negative: buf[strlen(buf) - 1] = ... without a non-empty check, buf[len - 1] after len = strlen(...), buf[n] after an unchecked read()/recv()/readlink() result, and literal negative indexes into arrays.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-124
Severity High
SARIF level error
Kind sast
Languages C, C++
CWE CWE-124
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:H/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:H/DI:H/EX:H/EC:N/P:H
Tags buffer-underwrite memory cwe-124
Source internal/sast/rules/vnx-124.rego

Overview

VNX-124 maps to CWE-124: Buffer Underwrite (‘Buffer Underflow’). It reports:

  1. buf[strlen(buf) - 1] = ... with no check that the string is non-empty (the fgets newline-strip idiom: an empty line writes buf[-1]).
  2. buf[len - 1] = ... where len was assigned from strlen() a few lines above and is never compared before the write.
  3. buf[n] = '\0' (or buf[n - 1]) where n is the return value of read(), recv(), recvfrom(), recvmsg(), pread() or readlink(), which is -1 on error, and n is never compared before the write.
  4. A write through a literal negative index into an array declared in the same function.

What Gets Flagged

fgets(buf, size, stdin);
buf[strlen(buf) - 1] = '\0';                       // FLAGGED

ssize_t len = readlink(path, target, sizeof(target) - 1);
target[len] = 0;                                   // FLAGGED: len may be -1

size_t n = strlen(s);
s[n - 1] = 0;                                      // FLAGGED: n may be 0

What Is Not Flagged

  • Guarded writes: if (len > 0 && buf[len - 1] == '\n'), if (*s && ...), if (n < 0) return;, while ((r = read(...)) > 0).
  • Reads such as s[n - 1] == '\n', and s[strcspn(s, "\n")] = '\0'.
  • Negative indexes on pointers into the middle of an allocation (sds-style string headers).

Remediation

Check that a length is greater than zero, and that a read returned a non-negative count, before using it to index a write. Strip newlines with s[strcspn(s, "\n")] = '\0'.

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-124
// nosec vnx-124

Or record an ignore rule: vulnetix ignore add --rule vnx-124 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-124.rego, cli/internal/sast/docs/vnx-124.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.