Skip to content

VNX-786: Access of Memory Location Before Start of Buffer

C/C++ indexing with strlen()-1 or a read()/recv() result that is never checked, and literal negative indexes on declared arrays.

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

Overview

VNX-786 maps to CWE-786: Access of Memory Location Before Start of Buffer. It reports C and C++ indexing that reaches before the start of a buffer when a length is zero or a call failed:

  • X[strlen(Y) - 1] with no length or first-byte check in the three lines above
  • X[n - 1] where n was assigned from strlen() and never checked before the index
  • X[n] or X[n - 1] where n came from read(), recv(), recvfrom(), readlink() or pread(), which return -1 on error, and was never checked
  • a literal negative index (counts[-1]) on a name whose nearest declaration is an array

Negative indexes on pointers into the middle of a buffer (p[-1]) and lengths compared anywhere between the assignment and the index are not reported.

Why This Matters

line[strlen(line) - 1] = '\0' after fgets() writes line[-1] when the line is empty (an input starting with a NUL byte is enough). buf[n] = '\0' after a failed read() writes buf[-1]. Both corrupt the byte before the buffer, which is often a saved pointer or another variable.

What Gets Flagged

line[strlen(line) - 1] = '\0';          // FLAGGED: empty line writes line[-1]

ssize_t n = read(fd, buf, sizeof(buf) - 1);
buf[n] = '\0';                          // FLAGGED: n is -1 on error

Not flagged:

size_t len = strlen(s);
if (len > 0 && s[len - 1] == '\n')
    s[len - 1] = '\0';

Remediation

  1. Check the length is non-zero before subtracting one from it.
  2. Check read()/recv() results for < 0 (and == 0) before using them as an index.

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-786
// nosec vnx-786

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

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