VNX-1075: Unconditional Control Flow Transfer outside of Switch Block
A C goto that jumps backwards to a label earlier in the same function, building a loop from an unconditional jump. Backward gotos in C++ files are reported by VNX-1119.
| Field | Value |
|---|---|
| Rule ID | VNX-1075 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | C |
| CWE | CWE-1075 |
| 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 | unconditional-control-flow backward-goto cwe-1075 |
| Source | internal/sast/rules/vnx-1075.rego |
Overview
VNX-1075 maps to CWE-1075: Unconditional Control Flow Transfer outside of Switch Block. It reports a goto L; in a C file (.c, .h) whose label L: is defined earlier in the same function (no column-zero closing brace between them, at most 400 lines above). A retry that jumps forward to an error handler which then jumps back to the label (try_again: ... goto socket_err; ... socket_err: ... goto try_again;) is the same loop and is reported too.
The same backward goto in a C++ file (.cc, .cpp, .cxx, .hpp, .hh) is reported by VNX-1119, so one jump is one finding.
It does not report forward gotos to a cleanup or error label (the accepted C error-unwinding idiom), a backward goto into an error-handling tail section (the code after the label returns, exits, continues, breaks or jumps away at the label’s own nesting level before reaching the goto, so the jump cannot loop), a goto whose same-named label also appears below it in the function, a same-named label in an earlier function, computed gotos (goto *ptr), or goto text in comments (including a /* */ block whose lines carry no leading *) and strings.
Why This Matters
A backward goto is a loop without a loop header: its condition and bound are hidden at the bottom, so it is easy to make it spin forever (an EINTR retry with no limit) or to re-run setup that should run once.
What Gets Flagged
retry:
n = read(fd, buf, len);
if (n < 0 && errno == EINTR)
goto retry; // FLAGGED
Not flagged: if (!buf) goto err_close; with err_close: further down.
Remediation
- Write the loop as
for,whileordo { } while, with an explicit condition and, for retries, a bound.
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-1075
// nosec vnx-1075
Or record an ignore rule: vulnetix ignore add --rule vnx-1075 --reason "...". See Suppressing findings.