Skip to content

VNX-191: Integer Underflow (Wrap or Wraparound)

Reports C/C++ length subtractions (len - HDR, len -= consumed, strlen(s) - 1) that size or index a memory operation with no prior check that the length is large enough, where the length is a function parameter or decoded from a message.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-191
Severity High
SARIF level error
Kind sast
Languages C, C++
CWE CWE-191
CAPEC CAPEC-92
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 integer-underflow arithmetic buffer cwe-191
Source internal/sast/rules/vnx-191.rego

Overview

VNX-191 maps to CWE-191: Integer Underflow (Wrap or Wraparound). Lengths in C are unsigned (size_t). Subtracting a header size from a length that is shorter than the header wraps to a value near SIZE_MAX, and the memcpy, read or malloc that uses it runs far past the buffer.

What Gets Flagged

  • A size argument of memcpy, memmove, memset, strncpy, strncat, malloc, calloc, realloc, read, recv, fread, fwrite, write, send (and std:: forms) written as len - x, where len is a length-like name handed in as a parameter or decoded from a message (ntohs(...), hdr->len).
  • An unsigned declaration initialised as a - b, or len -= x on an unsigned variable, whose result reaches such a call within 8 lines.
  • buf[strlen(buf) - 1], which indexes before the buffer when the string is empty.
int parse_packet(const uint8_t *pkt, size_t len, uint8_t *out)
{
	memcpy(out, pkt + HDR_LEN, len - HDR_LEN);   /* flagged */
}

void chomp(char *line)
{
	line[strlen(line) - 1] = '\0';               /* flagged */
}

Not flagged: a subtraction preceded within 10 lines by a comparison of the length (if (len < HDR_LEN) return -1;), a ternary or min(), constant minuends (sizeof(buf) - 1), pointer differences, lengths a data structure maintains itself (node->size - pos), and comments. Go and Java are not covered: Go panics on an out-of-range slice and Java has no unsigned lengths.

Remediation

if (len < HDR_LEN)
	return -1;
memcpy(out, pkt + HDR_LEN, len - HDR_LEN);

size_t n = strlen(line);
if (n > 0 && line[n - 1] == '\n')
	line[n - 1] = '\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-191
// nosec vnx-191

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

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