VNX-588: Attempt to access child of a non-structure pointer
Reports the address of a scalar variable cast to a structure pointer in C and C++. Casts of structures (the sockaddr idiom), arrays and pointer values are not reported.
| Field | Value |
|---|---|
| Rule ID | VNX-588 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | C, C++ |
| CWE | CWE-588 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L |
| Tags | pointer-cast-object cwe-588 |
| Source | internal/sast/rules/vnx-588.rego |
Overview
VNX-588 maps to CWE-588: Attempt to Access Child of a Non-structure Pointer. It reports (struct T *)&name, (T *)&name and reinterpret_cast<T *>(&name) (where T is a struct or class, or a typedef of a struct or union, declared in the same file) when the nearest declaration of name within the 60 lines above declares it as a scalar (int, long, char, double, size_t, the fixed-width integer types).
Why This Matters
A member access through such a pointer reads or writes past the end of the scalar, into whatever the compiler placed next to it on the stack or in static storage. That is memory corruption the type system was meant to prevent.
What Gets Flagged
int flags = 0;
struct header *h = (struct header *)&flags;
unsigned long count;
((struct node *) &count)->next = 0;
uint32_t word = 0;
msg_hdr_t *h = (msg_hdr_t *)&word; /* typedef struct { ... } msg_hdr_t; */
long value = 0;
auto *p = reinterpret_cast<Packet *>(&value);
Not flagged: (struct sockaddr *)&addr where addr is a struct sockaddr_in, (struct frame *)buf for a char buf[64], (struct frame *)&buf[0], (struct frame *)data for a void *, scalars declared further away or in another file, comments and strings.
Remediation
- Declare a variable of the structure type and access its members directly.
- To reinterpret bytes, copy them with
memcpyinto a correctly typed object.
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-588
// nosec vnx-588
Or record an ignore rule: vulnetix ignore add --rule vnx-588 --reason "...". See Suppressing findings.