VNX-128: Wrap-around Error
Reports C/C++ allocations (malloc, alloca, realloc, new T[]) whose size multiplies a count read from input (atoi/strtoul, ntohl, getenv, scanf/fread into &n) with no overflow check, so a large count wraps the size around.
| Field | Value |
|---|---|
| Rule ID | VNX-128 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | C, C++ |
| CWE | CWE-128 |
| 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 | wraparound integer cwe-128 |
| Source | internal/sast/rules/vnx-128.rego |
Overview
VNX-128 maps to CWE-128: Wrap-around Error. It reports an allocation whose size is a multiplication involving a count read from outside the program, with no overflow check:
malloc/xmalloc/alloca(n * size),realloc(p, n * size)andnew T[a * b];- where
nis the result ofatoi/atol/strtol/strtoul(and thellvariants),ntohl/ntohs/be*toh/le*tohorgetenv, or a variable filled byscanf/fscanf/sscanf(&n),fread(&n, ...)orread(fd, &n, ...), within the 20 lines above, or such a call written directly in the product; - also the two-step form
size_t bytes = n * size; malloc(bytes).
A large count makes the product wrap around to a small value, the allocation succeeds, and the code that fills n elements overruns it.
What Gets Flagged
int count = atoi(argv[1]);
int *items = malloc(count * sizeof(int)); // FLAGGED
uint32_t n = ntohl(wire[0]);
recs = realloc(recs, n * sizeof(struct rec)); // FLAGGED
scanf("%d %d", &rows, &cols);
int *grid = new int[rows * cols]; // FLAGGED
What Is Not Flagged
calloc()andreallocarray(), which check the multiplication.- A count compared with
<,<=,>or>=before the allocation, aSIZE_MAX/INT_MAXbound,__builtin_mul_overfloworckd_mul. - Counts that do not come from such a source (internal sizes, constants such as
MAX_ITEMS). - Counts that arrive through a function argument or a struct field (out of scope).
Remediation
Use calloc(n, size) or reallocarray(p, n, size), or check n > SIZE_MAX / size before multiplying.
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-128
// nosec vnx-128
Or record an ignore rule: vulnetix ignore add --rule vnx-128 --reason "...". See Suppressing findings.