VNX-680: Integer Overflow to Buffer Overflow
Detects C and C++ allocations whose size multiplies a count parsed or received from outside the program, with no overflow or range check between the read and the allocation.
| Field | Value |
|---|---|
| Rule ID | VNX-680 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | C, C++ |
| CWE | CWE-680 |
| 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 | integer-overflow-to-buffer cwe-680 |
| Source | internal/sast/rules/vnx-680.rego |
Overview
VNX-680 maps to CWE-680: Integer Overflow to Buffer Overflow. An allocation size computed as count * size wraps when count is large, so malloc returns a small buffer and the loop that fills count elements writes far past it. The rule reports the allocation when the count comes from outside the program and nothing checks it first.
What Gets Flagged
malloc, realloc, alloca, xmalloc, g_malloc, kmalloc, vmalloc, HeapAlloc, LocalAlloc, GlobalAlloc and C++ new T[...] whose size is a multiplication involving:
- a value parsed or decoded on the same line (
atoi,strtoland friends,ntohl,ntohs,beNNtoh,getenv), or - a variable assigned from one of those, or filled through
scanf/fscanf/sscanf,fread,read,recv,recvfrom,ReadFileorstd::cin >>or an extraction statement from any stream (in >> w >> h;), within the 20 lines above.
uint32_t count = ntohl(*(const uint32_t *)buf);
out = malloc(count * sizeof(struct record)); // FLAGGED
int *table = (int *)malloc(atoi(argv[1]) * sizeof(int)); // FLAGGED
fscanf(fp, "%u", &n);
items = realloc(items, n * width); // FLAGGED
uint8_t *pixels = new uint8_t[w * h * 4]; // FLAGGED (w, h read from a stream)
read(fd, &nent, sizeof nent);
size_t bytes = nent * sizeof(struct entry);
e = malloc(bytes); // FLAGGED: product computed above
int slots = atoi(arg);
if (slots <= 0) return NULL; // a lower bound only: not a check
p = malloc(slots * sizeof(long)); // FLAGGED
What Is Not Flagged
calloc(count, size)andreallocarray, which check the product.- A count compared against a bound, or guarded with
SIZE_MAX,INT_MAX,__builtin_mul_overfloworckd_mul, between the read and the allocation. - Products of constants or of internal counts (
cap * 2,MAX_ITEMS * sizeof(int),strlen(s) * sizeof(char)). - Comments and string literals.
Remediation
uint32_t count = ntohl(*(const uint32_t *)buf);
if (count > SIZE_MAX / sizeof(struct record)) {
return NULL;
}
struct record *out = calloc(count, sizeof(struct record));
References
- CWE-680: Integer Overflow to Buffer Overflow
- SEI CERT INT30-C: Ensure that unsigned integer operations do not wrap
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-680
// nosec vnx-680
Or record an ignore rule: vulnetix ignore add --rule vnx-680 --reason "...". See Suppressing findings.